Esta frase refere-se aos fork
e exec
chamadas do sistema¹. A chamada de sistema fork
cria um novo processo duplicando o processo de chamada: depois de executar fork
, há dois processos, cada qual com sua própria memória¹ com conteúdo inicialmente idêntico, exceto pelo valor de retorno da chamada de sistema fork
o ID do processo e muito poucas outras diferenças. A chamada do sistema exec
carrega uma imagem de programa de um arquivo e substitui a memória do processo existente por essa imagem.
A maneira de executar um programa no sentido usual é chamar fork
para criar um novo processo para o programa ser executado e, em seguida, chamar exec
no filho para substituir a cópia do programa original pelo código e dados do novo programa. Esse é o uso mais comum de fork
(geralmente com algumas coisas feitas antes de exec
, como configurar redirecionamentos de arquivos).
Executar exec
sem ter feito fork
pode ser visto como uma otimização de fazer fork
+ exec
e fazer o pai fazer exit
imediatamente depois. Não é exatamente equivalente porque fork
+ exec
/ exit
altera o pai do programa resultante, enquanto um exec
direto não o faz.
O sinalizador de processo 1 do Linux sinaliza processos que não chamaram exec
desde que foram bifurcados por seus pais, ou seja, filhos (ou netos, etc.) do processo original de seu programa. Chamar fork
sem chamar exec
tem vários usos. (Esta não é uma lista exaustiva, apenas alguns casos de uso comuns.)
- Alguns programas exploram vários processadores. Isso pode ser feito executando vários threads no mesmo processo (em seguida, todos os threads compartilham memória) ou executando processos separados em cada processador (eles não compartilham memória).
- A execução de processos separados é uma maneira de isolar algumas tarefas. Por exemplo, o Chrome mantém cada guia ou cada pequeno grupo de guias em um processo separado; Dessa forma, se uma guia estiver suspensa ou travar, ou se uma página da Web disparar uma falha de segurança, isso não afetará as guias exibidas por outros processos. Processos separados também podem ser úteis para executar tarefas diferentes com privilégios diferentes; por exemplo, o servidor OpenSSH executa a maior parte de seu código como um usuário não privilegiado e executa apenas o estágio de login final como root. Os shells usam
fork
para implementar subchaves (partes do script onde variáveis, redirecionamentos, etc. não afetam o script principal). -
Daemons costumam começar por “double forking”: quando o programa é executado, uma das primeiras coisas que ele faz é
fork
e, em seguida, o pai sai. Esse é o inverso daexec
“otimização” que mencionei acima, e é feito para isolar o processo do daemon de seu pai original e, em particular, para evitar o bloqueio do pai original se ele estivesse esperando que seu filho terminasse (como acontece por exemplo, quando você executa um programa em um shell sem&
).
¹ Existem nuances que não importam aqui e estão além do escopo desta resposta.