logo

fork() v C

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.

vytvoření vidličkové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