Systémové volání Fork se používá pro vytvoření nového procesu v systémech Linux a Unix, který se nazývá dětský proces , který běží souběžně s procesem, který volá fork() (nadřazený proces). Po vytvoření nového podřízeného procesu oba procesy provedou další instrukci následující po systémovém volání fork().
Podřízený proces používá stejný počítač (počítadlo programů), stejné registry CPU a stejné otevřené soubory, které používá nadřazený proces. Nepotřebuje žádné parametry a vrací celočíselnou hodnotu.
Níže jsou uvedeny různé hodnoty vrácené fork().
- Záporná hodnota : Vytvoření podřízeného procesu bylo neúspěšné.
- Nula : Návrat k nově vytvořenému podřízenému procesu.
- Pozitivní hodnota : Vráceno rodiči nebo volajícímu. Hodnota obsahuje ID procesu nově vytvořeného podřízeného procesu.

Poznámka: fork() je funkce založená na vláknech, pro získání správného výstupu spusťte program na místním systému.
Vezměte prosím na vědomí, že výše uvedené programy se nekompilují v prostředí Windows.
Příklad fork() v C
C
třída objektů v jazyce Java
#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;> }> |
>
>Výstup
Hello world!, process_id(pid) = 31 Hello world!, process_id(pid) = 32>
Příklad 2: Vypočítejte, kolikrát se vytiskne ahoj.
C
#include> #include> #include> int> main()> {> >fork();> >fork();> >fork();> >printf>(>'hello
'>);> >return> 0;> }> |
>
>Výstup
hello hello hello hello hello hello hello hello>
Vysvětlení
Počet vytištění „ahoj“ se rovná počtu vytvořených procesů. Celkový počet procesů = 2n, kde n je počet systémových volání rozvětvení. Takže zde n = 3, 23= 8 Uveďme nějaké názvy štítků pro tři řádky:
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>
Existuje tedy celkem osm procesů (nové podřízené procesy a jeden původní proces). Pokud bychom chtěli vztah mezi procesy znázornit jako stromovou hierarchii, bylo by to následující: Hlavní proces: P0 Procesy vytvořené 1. rozvětvením: P1 Procesy vytvořené 2. rozvětvením: P2, P3 Procesy vytvořené 3. rozvětvením: P4, P5, P6, P7
P0 / | P1 P4 P2 / P3 P6 P5 / P7>
Příklad 3: Předpovězte výstup následujícího programu.
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;> }> |
>
>Výstup
Hello from Parent! Hello from Child!>
Poznámka: Ve výše uvedeném kódu je vytvořen podřízený proces. fork() vrací 0 v podřízeném procesu a kladné celé číslo v nadřazeném procesu. Zde jsou možné dva výstupy, protože nadřazený proces a podřízený proces běží souběžně. Nevíme tedy, zda OS nejprve poskytne kontrolu nadřazenému procesu nebo podřízenému procesu.
Nadřazený proces a podřízený proces běží na stejném programu, ale to neznamená, že jsou totožné. OS těmto dvěma procesům přiděluje různá data a stavy a tok řízení těchto procesů může být odlišný. Viz následující příklad:
Příklad 4: Předpovězte výstup následujícího programu.
C
linuxové příkazy, které
#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;> }> |
abstraktní metody
>
>Výstup
Parent has x = 0 Child has x = 2>
nebo
Výstup
Child has x = 2 Parent has x = 0>
Zde změna globální proměnné v jednom procesu neovlivňuje dva další procesy, protože data/stav těchto dvou procesů se liší. A také rodič a dítě běží současně, takže jsou možné dva výstupy.
fork() vs exec()
Systémové volání fork vytvoří nový proces. Nový proces vytvořený fork() je kopií aktuálního procesu s výjimkou vrácené hodnoty. Na druhou stranu systémové volání exec() nahradí aktuální proces novým programem.
Problémy založené na C fork()
1. Proces spustí následující kód
C
for> (i = 0; i fork();> |
>
>
Celkový počet vytvořených podřízených procesů je (GATE-CS-2008)
(A) n
(B) 2^n – 1
(C) 2^n
(D) 2^(n+1) – 1
Podívejte se na řešení.
2. Zvažte následující fragment kódu:
C
if> (fork() == 0) {> >a = a + 5;> >printf>(>'%d, %d
'>, a, &a);> }> else> {> >a = a –5;> >printf>(>'%d, %d
'>, a, &a);> }> |
>
>
Nechť u, v jsou hodnoty vytištěné nadřazeným procesem a x, y jsou hodnoty vytištěné podřízeným procesem. Která z následujících možností je PRAVDA? (GATE-CS-2005)
(A) u = x + 10 a v = y
(B) u = x + 10 a v! = y
(C) u + 10 = x a v = y
(D) u + 10 = x a v! = y
Podívejte se na řešení.
3. Předpovězte výstup níže uvedeného programu.
C
dynamické pole v Javě
#include> #include> int> main()> > >fork();> >fork() && fork()> |
>
>
Řešení viz toto
Související články:
- C program pro demonstraci fork() a pipe()
- Zombie a osiřelé procesy v C
- fork() a pomocí něj vytvořené černobílé procesy sdílené v paměti