Chamada de garfo e recursão

5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    fork();
    fork();
    fork();

    puts("hi");

    return 0;
}

Este programa imprime 8 vezes "oi" e sai. Por quê? Não é cada fork chamando main recursivamente como em: f(): "hi"; f() ?

    
por Dr. KingSchultz 29.11.2012 / 19:50

2 respostas

10

Não, fork não é "recursivo" no significado tradicional de recursão. Uma chamada para fork() duplica o processo atual para "retornar duas vezes". Para o processo filho, o valor de retorno é 0 e, para o pai, o valor de retorno é o PID filho. fork() não reinicia main - seria mais parecido com fork seguido por exec .

Seu programa funciona assim. Primeiro vamos inserir alguns números de linha:

 1: #include <stdio.h>
 2: #include <stdlib.h>
 3: #include <string.h>
 4:
 5: int main(int argc, char *argv[])
 6: {
 7:    fork();
 8:    fork();
 9:    fork();
10:
11:    puts("hi");
12:
13:    return 0;
14: }

Digamos que você inicie seu programa e receba um PID de P .

  • Após a linha 7, a chamada para fork resulta em dois processos separados, ambos na linha 8 , um com PID P (o original) e um com um pid de C1 (o novo filho).

  • P executa a linha 8 e gera um novo filho, com PID C2 . Ambos P e C2 estão na linha 9 agora. Enquanto isso, C1 executa a linha 8 e gera um novo filho, CC1 . Ambos CC1 e C1 estão na linha 9 também. (Não totalmente relevante, mas a ordem em que as duas sentenças acima ocorrem é indeterminada. Elas podem acontecer simultaneamente em sistemas com vários processadores.)

Agora, há um total de quatro processos: P , C1 , C2 e CC1 . Como você pode ver, cada fork sucessiva dobra a quantidade de processos. Como há 3% de chamadasfork, você acaba com 2 3 ou 8 processos. A genealogia parece algo como:

P (initial process, started by you)
+-- C1 (created on line 7)
|   +-- CC1 (created on line 8)
|   |   +-- CCC1 (created on line 9)
|   +-- CC2 (created on line 9)
+-- C2 (created on line 8)
|   +-- CC3 (created on line 9)
+-- C3 (created on line 9)

Cada processo é criado por seu pai na árvore.

    
por 29.11.2012 / 20:14
3
                           main()
                             |
                             |
                      fork()  ------------------
                              |                 |
                     fork()   -------        -------
                              |     |        |      |
                   fork()   ----   ----     ---    ---
                            |  |   |   |    |  |   |  |

Esta é a árvore de processos do código acima que é como o fork () funciona. e por que sua impressão 8 significa sempre 2 power n (onde n é o número de chamadas, ou seja, fork ().

    
por 30.11.2012 / 05:23

Tags