Depois do fork (), onde a criança começa sua execução?

21

Estou tentando aprender programação UNIX e me deparei com uma pergunta sobre fork (). Eu entendo que fork () cria um processo idêntico do processo atualmente em execução, mas onde ele inicia? 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 é:

This is most definitely the parent process
Which process printed this?
Which process printed this?

Eu pensei que fork() cria um mesmo processo, então, inicialmente, que naquele programa, a chamada fork() seria chamada recursivamente para sempre. Eu acho que o novo processo criado a partir de fork() começa após a chamada fork() ?

Se eu adicionar o código a seguir, para diferenciar entre 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?

    
por Gilles 28.11.2010 / 03:36

4 respostas

23

O novo processo será criado dentro da chamada fork() e começará retornando como o pai. O valor de retorno (que você armazenou em retval ) de fork() será:

  • 0 no processo filho
  • O PID do filho no processo pai
  • -1 no pai se houve uma falha (não há filho, naturalmente)

Seu código de teste funciona corretamente; armazena o valor de retorno de fork() em child_pid e usa if para verificar se é 0 ou não (embora não verifique um erro)

    
por 28.11.2010 / 03:48
13

I thought that fork() creates a same process, so I initially that that in that program, the fork() call would be recursively called forever. I guess that new process created from fork() starts after the fork() call?

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, pois eles necessariamente compartilham o mesmo código, consulte A resposta de Michael Mrozek.

    
por 28.11.2010 / 13:32
0

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
    
por 17.08.2013 / 21:29
-1

qualquer que seja o código logo após o fork() , é copiado para o processo filho, e não misture o processo pai e filho, eles são duas entidades diferentes, que têm o mesmo ambiente (duplicado, não compartilhado).

Agora veja sua saída ...

    
por 17.08.2013 / 17:56

Tags