La chiamata di sistema Fork viene utilizzata per creare un nuovo processo nei sistemi Linux e Unix, chiamato the processo figlio , che viene eseguito in concomitanza con il processo che effettua la chiamata fork() (processo genitore). Dopo aver creato un nuovo processo figlio, entrambi i processi eseguiranno l'istruzione successiva successiva alla chiamata di sistema fork().
Il processo figlio utilizza lo stesso PC (contatore di programma), gli stessi registri della CPU e gli stessi file aperti utilizzati nel processo padre. Non accetta parametri e restituisce un valore intero.
Di seguito sono riportati i diversi valori restituiti da fork().
- Valore negativo : La creazione di un processo figlio non è riuscita.
- Zero : restituito al processo figlio appena creato.
- Valore positivo : restituito al genitore o al chiamante. Il valore contiene l'ID processo del processo figlio appena creato.

Nota: fork() è una funzione basata sul threading, per ottenere l'output corretto eseguire il programma su un sistema locale.
Tieni presente che i programmi di cui sopra non vengono compilati in un ambiente Windows.
Esempio di fork() in C
C
shweta tiwari
#include> #include> #include> int> main()> {> > >// make two process which run same> >// program after this instruction> >pid_t p = fork();> >if>(p<0){> >perror>(>'fork fail'>);> >exit>(1);> >}> >printf>(>'Hello world!, process_id(pid) = %d
'>,getpid());> >return> 0;> }> |
>
>Produzione
Hello world!, process_id(pid) = 31 Hello world!, process_id(pid) = 32>
Esempio 2: calcolare il numero di volte in cui viene stampato ciao.
C
#include> #include> #include> int> main()> {> >fork();> >fork();> >fork();> >printf>(>'hello
'>);> >return> 0;> }> |
>
>Produzione
hello hello hello hello hello hello hello hello>
Spiegazione
Il numero di volte in cui viene stampato 'ciao' è uguale al numero di processi creati. Numero totale di processi = 2N, dove n è il numero di chiamate di sistema fork. Quindi qui n = 3, 23= 8 Inseriamo alcuni nomi di etichette per le tre righe:
fork (); // Line 1 fork (); // Line 2 fork (); // Line 3 L1 // There will be 1 child process / // created by line 1. L2 L2 // There will be 2 child processes / / // created by line 2 L3 L3 L3 L3 // There will be 4 child processes // created by line 3>
Quindi ci sono un totale di otto processi (nuovi processi figli e un processo originale). Se vogliamo rappresentare la relazione tra i processi come una gerarchia ad albero sarebbe la seguente: Il processo principale: P0 Processi creati dal 1° fork: P1 Processi creati dal 2° fork: P2, P3 Processi creati dal 3° fork: P4, P5, P6, P7
P0 / | P1 P4 P2 / P3 P6 P5 / P7>
Esempio 3: prevedere l'output del seguente programma.
C
#include> #include> #include> #include> void> forkexample()> {> >pid_t p;> >p = fork();> >if>(p<0)> >{> >perror>(>'fork fail'>);> >exit>(1);> >}> >// child process because return value zero> >else> if> ( p == 0)> >printf>(>'Hello from Child!
'>);> > >// parent process because return value non-zero.> >else> >printf>(>'Hello from Parent!
'>);> }> int> main()> {> >forkexample();> >return> 0;> }> |
>
>Produzione
Hello from Parent! Hello from Child!>
Nota: Nel codice precedente viene creato un processo figlio. fork() restituisce 0 nel processo figlio e un intero positivo nel processo genitore. Qui sono possibili due output perché il processo genitore e il processo figlio vengono eseguiti contemporaneamente. Quindi non sappiamo se il sistema operativo darà prima il controllo al processo genitore o al processo figlio.
Il processo genitore e il processo figlio eseguono lo stesso programma, ma ciò non significa che siano identici. Il sistema operativo assegna dati e stati diversi per questi due processi e il flusso di controllo di questi processi può essere diverso. Vedi il prossimo esempio:
Esempio 4: prevedere l'output del seguente programma.
C
arachidi contro arachidi
#include> #include> #include> #include> > void> forkexample()> {> >int> x = 1;> >pid_t p = fork();> >if>(p<0){> >perror>(>'fork fail'>);> >exit>(1);> >}> >else> if> (p == 0)> >printf>(>'Child has x = %d
'>, ++x);> >else> >printf>(>'Parent has x = %d
'>, --x);> }> int> main()> {> >forkexample();> >return> 0;> }> |
>
>Produzione
Java fattoriale
Parent has x = 0 Child has x = 2>
O
Produzione
Child has x = 2 Parent has x = 0>
In questo caso, la modifica della variabile globale in un processo non influisce su altri due processi perché i dati/stato dei due processi sono diversi. Inoltre, genitore e figlio vengono eseguiti contemporaneamente, quindi sono possibili due output.
fork() vs exec()
La chiamata di sistema fork crea un nuovo processo. Il nuovo processo creato da fork() è una copia del processo corrente ad eccezione del valore restituito. D'altra parte, la chiamata di sistema exec() sostituisce il processo corrente con un nuovo programma.
Problemi basati sul fork del C()
1. Un processo esegue il seguente codice
C
for> (i = 0; i fork();> |
>
>
Il numero totale di processi figlio creati è (GATE-CS-2008)
(UN
(B) 2^n – 1
(C) 2^n
(D) 2^(n+1) – 1
Vedi questo per una soluzione.
2. Considera il seguente frammento di codice:
C
if> (fork() == 0) {> >a = a + 5;> >printf>(>'%d, %d
'>, a, &a);> }> else> {> >a = a –5;> >printf>(>'%d, %d
'>, a, &a);> }> |
>
>
Siano u, v i valori stampati dal processo genitore e x, y i valori stampati dal processo figlio. Quale delle seguenti affermazioni è VERA? (GATE-CS-2005)
(A) u = x + 10 e v = y
(B) u = x + 10 e v != y
(C) u + 10 = x e v = y
(D) u + 10 = x e v != y
programmazione int c senza segno
Vedi questo per una soluzione.
3. Prevedere l'output del programma seguente.
C
#include> #include> int> main()> > >fork();> >fork() && fork()> |
>
>
Vedi questo per la soluzione
Articoli Correlati :
- Programma C per dimostrare fork() e pipe()
- Processi Zombie e Orfani in C
- fork() e processi in bianco e nero condivisi in memoria creati utilizzandolo