2012-02-12 22 views
14

Ho questo esempio di codice, ma non capisco perché questo codice crea 5 processi più l'originale. (6 processo totale)Non capisco questo esempio di fork()

#include <unistd.h> 

int main(void) { 
    int i; 
    for (i = 0; i < 3; i++) { 
     if (fork() && (i == 1)) { 
      break; 
     } 
    } 
} 

Process graph

+3

disegnare un albero di processi. –

risposta

30

fork() divide un processo in due e restituisce 0 (se questo processo è il figlio) o il PID del figlio (se questo processo è il genitore). Quindi, questa linea:

if (fork() && (i == 1)) break; 

dice: "Se questo è il processo padre, e questa è la seconda volta attraverso il ciclo, rompere fuori dal giro". Questo significa che il ciclo viene eseguito in questo modo:

  • i == 0: La prima iterazione del ciclo, i è 0, creiamo due processi, sia inserendo il loop i == 1. totale ora due processi

  • i == 1: entrambi questi processi forchetta, ma due di loro non continuare a iterare a causa della linea if (fork() && (i == 1)) break; (i due che non continui sono entrambi i genitori negli inviti forcella). Totale quattro processi, ma solo due di quelli stanno continuando in loop.

  • i == 2: Ora, i due che continuano il ciclo entrambi i fork, con conseguente 6 processi.

  • i == 3: Tutti i 6 processi uscire dal ciclo (dal i < 3 == false, non c'è più looping)

+1

Ben scritto :) – Evert

+0

come puoi vedere nella foto (il risultato del libro), nella i == 2 solo una forchetta di processo(), l'altra no ??? e questo è ciò che non posso capire, se è il bambino !!!! – cleo

+0

grazie per il tuo aiuto – cleo

2

Nei bambini elabora il ciclo continua a scorrere. Quindi producono anche nuovi processi.

3

il ciclo parte da i==0 a i==2.

Nella prima iterazione, il processo originale (p0) creare un altro (p1)

Nella seconda iterazione, p0 e p1 creare un nuovo processo ciascuno (p2 e p3), e rompere (Da i==1 e fork restituiscono un valore diverso da zero al padre).

Nella terza iterazione, p2 e p3 creare un nuovo processo ciascuno (p4 e p5).

Quindi, finalmente, hai 5 nuovi processi.

5

posso contare sei processi (X) qui:

i=0   fork() 
      / \ 
i=1 fork()  fork() 
    / \>0  / \>0 
     | X break | X break 
i=2 fork()  fork() 
    /\  /\ 
    X X   X X 
+0

qui il risultato non è come quello che ho nella foto: s – cleo

+0

grazie per il tuo aiuto – cleo

3

Per prima cosa avere un processo Considerare le iterazioni del ciclo:

i = 0 

Il primo processo chiama fork. Ora abbiamo 2 processi.

i = 1 

I due processi chiama fork. Ora abbiamo 4.

Fork restituisce 0 nei processi appena creati: due processi interromperanno il ciclo e due continueranno nel ciclo.

i = 2 

I due processi rimanenti chiamano fork. Otteniamo 2 nuovi processi (per un totale di 6).

6

Nel processo padre, fork() restituisce il PID del processo secondario e nel processo figlio restituisce 0. Con questo in mente, guarda ogni iterazione del ciclo for: (Diciamo per semplicità bene che il PID del processo originale è 1)

  1. i == 0
    • processo 1: i == 0, forcella torna PID del processo figlio (per esempio 2) (2 = 0), true & & false == false, quindi non si rompono.
    • Processo 2: i = 0, fork restituisce 0, false & & false == false, quindi non si interrompe.
  2. i == 1
    • Processo 1: i == 1, forcella torna PID del processo figlio (diciamo 3), vero & & vero == true, in modo da rompere.
    • Processo 2: i == 1, fork restituisce il PID del processo figlio (ad esempio 4), vero & & true == true, quindi interruzione.
    • Processo 3: i == 1, la forcella restituisce 0, false & & true == false, quindi non interrompere.
    • Processo 4: i == 1, la forcella restituisce 0, false & & true == false, quindi non interrompere.
  3. i == 2
    • Processo 1 è fuori dal giro.
    • Il processo 2 è fuori dal ciclo.
    • Processo 3: i == 2, forcella torna PID del processo figlio (diciamo 5), vero & & falso == false, in modo da non rompere
    • Processo 4: i == 2, forcella torna PID processo figlio (per esempio 6), vero & & falso == false, in modo da non rompere
    • processo 5: i == 2, restituisce forcella 0, false & & falso == false, in modo da non rompere
    • Processo 6: i == 2, fork restituisce 0, false & & false == false, quindi non si rompono
  4. i == 3 così fatto con loop.
+0

6 processo più INT così 7 processo ??? – cleo

+0

No, solo i 6 processi. –

12

Se il processo principale ha pid A e B - F sono sottoprocessi PID, quindi:

A spawns B   i=0 
A spawns C   i=1 
C run from 'fork' i=1 
C spawns D   i=2 
B run from 'fork' i=0 
B spawns E   i=1 
D run from 'fork' i=2 
E run from 'fork' i=1 
E spawns F   i=2 
F run from 'fork' i=2 

Dove i è il valore della i del (sotto) processo di contesto. Poiché fork crea una copia esatta del processo in esecuzione, verrà copiata anche la variabile i. Quando A spawns B, i è 0. Quando A spawns C, i è 1. Il processo A ora esce dal ciclo for poiché i == 1.

Ora il sottoprocesso C inizia a funzionare, con i == 1. Si noti che non si romperà all'interno del ciclo for da fork(), in C punto di spawning, restituisce 0. Al contrario, looping, aumentando i in 2, spawn D e exit a causa delle condizioni del ciclo for.

Il sottoprocesso B ha i == 0, quando viene avviato. Genera il sottoprocesso E e si interrompe all'interno del ciclo. (I == 1)

E così via ...

Quando si tyring di scoprire di cosa come questi, posso darvi un consiglio:

Fai variabili intermedie e stamparle.

ho modificato il codice, in modo che esso stampa le cose che ho appena descritto:

#include <unistd.h> 
#include <stdio.h> 

int main(void) { 
    int i; 
    for (i= 0; i < 3; ++i) { 
     int f = fork(); 
     printf("%i\tspawns\t%i\ti=%i\n", getpid(), f, i); 
     if (f && (i == 1)) 
      break; 
    } 

    getchar(); 
} 
+2

spiegazione perfetta grazie mille – cleo

Problemi correlati