Como o fork e o exec funcionam?

17

Eu não tenho muita experiência, apenas tentando me envolver nos processos, como eles interpretam o hardware do nível do usuário.

Assim, quando um comando é disparado de um shell, fork() herda um processo filho dele e exec() carrega o processo filho para a memória e executa.

  1. Se o processo filho contiver todos os atributos do processo pai (que é o processo original), qual é a necessidade desse processo filho? O processo original também poderia ter sido carregado na memória.
  2. Esse conceito fork e exec se aplica a todo o programa executável no UNIX? Gosta de script de shell também ou apenas para comandos? Aplica-se também aos comandos internos do shell?
  3. Quando o conceito copy on write é usado se eu executar um comando / script?

Desculpe por fazer muitas perguntas de cada vez, mas todas essas perguntas me vêm à mente quando penso em qualquer execução de comando.

    
por PriB 17.01.2015 / 20:08

4 respostas

21

So when a command is fired from a shell, fork() inherits a child process of it and exec() loads the child process to the memory and executes.

Não é bem assim. fork() clona o processo atual, criando uma criança idêntica. exec() carrega um novo programa no processo atual, substituindo o existente.

My qs is:

If the child process contains all the attributes of the parent process(which is the original process), then what is the need of this child process? The original process also could have been loaded to the memory.

A necessidade é porque o processo pai não quer terminar ainda; ele quer que um novo processo saia e faça algo ao mesmo tempo que continua a executar também.

Does this fork and exec concept apply to all the executable program in UNIX?Like for shell script also or only for commands? Does it also apply for shell builtin commands?

Para comandos externos, o shell faz um fork() para que o comando seja executado em um novo processo. Builtins são apenas executados diretamente pelo shell. Outro comando notável é exec , que informa ao shell para exec() do programa externo sem primeiro fork() ing. Isso significa que o shell em si é substituído pelo novo programa e, portanto, não está mais disponível para o programa retornar quando ele sai. Se você disser, exec true , então /bin/true substituirá seu shell e sairá imediatamente, deixando nada em execução no seu terminal, então ele será fechado.

when copy on write concept is used if I'll execute a command/script?

De volta à era da pedra, fork() teve que copiar toda a memória no processo de chamada para o novo processo. Copiar em gravação é uma otimização em que as tabelas de páginas são configuradas de modo que os dois processos iniciem o compartilhamento de toda a mesma memória, e somente as páginas gravadas por um ou outro processo são copiadas quando necessário.

    
por 17.01.2015 / 23:37
6
  1. Para alguns programas, o processo filho faz uma coisa (ler de uma porta serial, gravar no terminal) e o processo pai continua fazendo outra coisa (ler do terminal, gravar na porta serial). Outro exemplo clássico é o processo filho faz um ponto de verificação de qualquer cálculo de execução longa que está ocorrendo. Principalmente, o processo filho faz alguma configuração, como alterar o diretório, redefinir manipuladores de sinais ou redefinir descritores de arquivos, e chama execve() para se sobrepor a códigos diferentes.
  2. fork() e exec() se aplicam a todos os executáveis - na verdade, juntamente com argc e argv, e pipes, fork e exec são o que distinguem o Unix de outros sistemas operacionais. Algumas especializações ou generalizações de fork() existem, como vfork() do BSD, rfork() do Plan 9 e Linux ' clone() , mas o principal permanece o mesmo.
  3. "copiar na gravação" não é exibido para o usuário, é mais uma técnica para otimizar a criação de um processo filho e durante sua execução. A pilha de chamadas e o heap (memória alocada com malloc() , ou mesmo variáveis de escopo estáticas ou globais) podem ser "copy on write". Quando um processo filho é criado com uma chamada fork() , o kernel configuraria o processo filho para ter exatamente as mesmas páginas de memória que o heap e a pilha do processo pai. Se o hardware (unidade de gerenciamento de memória) detectar uma gravação do heap ou pilha, o kernel obterá uma nova página física de memória, copiará a página do pai para a nova página e mapeará essa nova página na pilha ou heap do processo filho. Isso constitui uma otimização, pois o kernel gasta menos tempo configurando os mapeamentos de páginas do que para copiar pilha e heap completamente para o processo filho.
por 17.01.2015 / 21:30
4
If the child process contains all the attributes of the parent process (which is the original process), then what is the need of this child process? The original process also could have been loaded to the memory.

Esta questão é muito ilustrativamente respondida, dando uma olhada nas implementações mais antigas do Unix, que tiveram que trabalhar sob restrições severas de memória e tinham apenas um processo de execução no espaço de memória / endereço de cada vez.

A multitarefa foi obtida trocando-se um processo para o disco e trocando um processo diferente.

Agora, a chamada do sistema fork era quase a mesma: ele trocava um processo para o disco, mas em vez de trocar outro processo, ele dava à cópia na memória outro ID do processo e retornava a ela. E esse foi um momento oportuno para esse processo decidir apenas exec em outro executável, afinal.

fork + exec , portanto, não sofreu sobrecarga perceptível durante a desova: você tinha que trocar seu processo para o disco de qualquer forma, e você tinha a antiga imagem do processo em locais de memória viáveis de qualquer maneira.

Com quantidades crescentes de unidades de gerenciamento de memória e memória disponíveis e vários processos em memória, o custo inicialmente insignificante de um fork tornou-se um pouco mais incômodo para algumas arquiteturas: assim nasceu vfork .

    
por 18.01.2015 / 15:41
2

Para tornar isso tão fácil de entender quanto possível, usarei uma analogia. Vamos assar uma torta!

Pegamos o livro de receitas e começamos a ler e a preparar uma torta de ruibarbo de morango (minha favorita), com uma massa artesanal. Quase tudo o que precisamos é na cozinha, exceto os ovos e as frutas, mas como vivemos em uma fazenda e a fruta está na estação, isso não é um problema. o problema é que o forno está quebrado e não há tempo suficiente para fazer tudo. Não seria bom ter mais de um de mim?

garfo () para o resgate. Agora há dois de mim. e nós dois vamos para a cozinha para começar a fazer a massa de torta. oops. Então, olhamos para o retorno do garfo. Eu tenho um grande número que ele tem zero, então eu vou para a cozinha enquanto ele sai para o galinheiro e jardim. Como eu ando passado o forno eu garfo () novamente, olhe para o valor de retorno: chatice eu tenho zero. Ele continua a farinha enquanto eu olho para o forno quebrado. Eu abro a porta, sem luz, eu fecho a porta. Alguém sabe como consertar um forno?

exec () para o resgate. Eu alcanço o voltímetro no meu cinto de ferramentas, a lâmpada pode ser diagnóstica, então eu verifico a energia, na verdade tropeçar disjuntor, correção fácil. enquanto ando até o painel do disjuntor, vejo um companheiro pegando ruibarbo. Que nojo! Eu prefiro torta de seda de chocolate.

    
por 17.01.2015 / 21:31

Tags