Estou tentando aprender a programação do UNIX e me deparei com uma pergunta sobre fork (). Entendo que o fork () cria um processo idêntico ao processo em execução no momento, mas por onde começa? Por exemplo, se eu tiver código
int main (int argc, char **argv)
{
int retval;
printf ("This is most definitely the parent process\n");
fflush (stdout);
retval = fork ();
printf ("Which process printed this?\n");
return (EXIT_SUCCESS);
}
A saída é:
Este é definitivamente o processo pai
Qual processo imprimiu isso?
Qual processo imprimiu isso?
Eu pensei que fork()
cria o mesmo processo, então eu inicialmente que naquele programa, a chamada fork()
seria chamada recursivamente para sempre. Eu acho que o novo processo criado a partir de fork()
inicia após a chamada fork()
?
Se eu adicionar o código a seguir, para diferenciar um processo pai e filho,
if (child_pid = fork ()) printf ("This is the parent, child pid is %d\n", child_pid);
else printf ("This is the child, pid is %d\n",getpid ());
após a chamada fork (), onde o processo filho inicia sua execução?
O novo processo será criado dentro da chamada fork()
e começará retornando dela como o pai. O valor de retorno (que você armazenou em retval
) de fork()
será:
Seu código de teste funciona corretamente; ele armazena o valor de retorno de fork()
em child_pid
e usa if
para verificar se é 0 ou não (embora não verifique se há um erro)
Eu pensei que fork () cria o mesmo processo, então, inicialmente, que nesse programa, a chamada fork () seria chamada recursivamente para sempre. Eu acho que o novo processo criado a partir de fork () inicia após a chamada fork ()?
Sim. Vamos numerar as linhas:
int main (int argc, char **argv)
{
int retval; /* 1 */
printf ("This is most definitely the parent process\n"); /* 2 */
fflush (stdout); /* 3 */
retval = fork (); /* 4 */
printf ("Which process printed this?\n"); /* 5 */
return (EXIT_SUCCESS); /* 6 */
}
O fluxo de execução é:
caller process fork() → ...
↘
original program exec() → 2 → 3 → 4 → 5 → 6
↘
forked program 5 → 6
... o que explica exatamente a saída que você recebeu.
Se você quiser saber como o programa original e bifurcado pode se comportar de maneira diferente, uma vez que necessariamente compartilham o mesmo código, consulte resposta de Michael Mrozek.
A verdadeira solução para isso é
switch (fork()) {
case -1 :
fprintf (stderr, "fork failed (%s)\n", strerror(errno));
break;
case 0 : // child process comes here
break;
default : // parent process
break;
}
// all continue here