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.