logo

widelec() w C

Wywołanie systemowe Fork służy do tworzenia nowego procesu w systemach Linux i Unix, który nazywa się proces potomny , który działa równolegle z procesem wywołującym funkcję fork() (proces nadrzędny). Po utworzeniu nowego procesu potomnego oba procesy wykonają następną instrukcję po wywołaniu systemowym fork().

Proces potomny używa tego samego komputera (licznika programów), tych samych rejestrów procesora i tych samych otwartych plików, których używa proces nadrzędny. Nie przyjmuje żadnych parametrów i zwraca wartość całkowitą.



Poniżej znajdują się różne wartości zwracane przez fork().

  • Ujemna wartość : Utworzenie procesu potomnego nie powiodło się.
  • Zero : Powrót do nowo utworzonego procesu potomnego.
  • Wartość dodatnia : Powrót do rodzica lub osoby dzwoniącej. Wartość zawiera identyfikator procesu nowo utworzonego procesu potomnego.

tworzenie procesu fork

Notatka: fork() jest funkcją opartą na wątkach, aby uzyskać poprawny wynik, uruchom program w systemie lokalnym.



Należy pamiętać, że powyższe programy nie kompilują się w środowisku Windows.

Przykład fork() w C

C




wielowątkowość w Javie



#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;> }>

>

>

Wyjście

Hello world!, process_id(pid) = 31 Hello world!, process_id(pid) = 32>

Przykład 2: Oblicz, ile razy zostanie wyświetlone powitanie.

C




#include> #include> #include> int> main()> {> >fork();> >fork();> >fork();> >printf>(>'hello '>);> >return> 0;> }>

>

>

Wyjście

hello hello hello hello hello hello hello hello>

Wyjaśnienie

Liczba wydruków „hello” jest równa liczbie utworzonych procesów. Całkowita liczba procesów = 2N, gdzie n jest liczbą wywołań systemowych typu fork. Zatem tutaj n = 3, 23= 8 Dodajmy nazwy etykiet dla trzech linii:

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>

Zatem istnieje w sumie osiem procesów (nowe procesy potomne i jeden proces oryginalny). Jeśli chcielibyśmy przedstawić relację pomiędzy procesami w postaci hierarchii drzewa, wyglądałoby to następująco: Proces główny: P0 Procesy utworzone przez 1. rozwidlenie: P1 Procesy utworzone przez 2. rozwidlenie: P2, P3 Procesy utworzone przez 3. rozwidlenie: P4, P5, P6, P7

 P0 / |  P1 P4 P2 /   P3 P6 P5 / P7>

Przykład 3: Przewiduj wyjście następującego 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;> }>

>

>

Wyjście

Hello from Parent! Hello from Child!>

Notatka: W powyższym kodzie tworzony jest proces potomny. fork() zwraca 0 w procesie potomnym i dodatnią liczbę całkowitą w procesie nadrzędnym. W tym przypadku możliwe są dwa wyjścia, ponieważ proces nadrzędny i proces potomny działają jednocześnie. Nie wiemy więc, czy system operacyjny najpierw przekaże kontrolę procesowi nadrzędnemu, czy procesowi potomnemu.

Proces nadrzędny i proces potomny uruchamiają ten sam program, ale to nie znaczy, że są identyczne. System operacyjny przydziela tym dwóm procesom różne dane i stany, a przepływ sterowania tymi procesami może być różny. Zobacz następny przykład:

Przykład 4: Przewiduj wyjście następującego programu.

C




jak zaktualizować w Javie

#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;> }>

>

>

Wyjście

Parent has x = 0 Child has x = 2>

Lub

Wyjście

Child has x = 2 Parent has x = 0>

W tym przypadku zmiana zmiennej globalnej w jednym procesie nie wpływa na dwa inne procesy, ponieważ dane/stan obu procesów są różne. A także rodzic i dziecko działają jednocześnie, więc możliwe są dwa wyjścia.

fork() vs exec()

Wywołanie systemowe fork tworzy nowy proces. Nowy proces utworzony przez fork() jest kopią bieżącego procesu, z wyjątkiem zwróconej wartości. Z drugiej strony wywołanie systemowe exec() zastępuje bieżący proces nowym programem.

Problemy oparte na C fork()

1. Proces wykonuje następujący kod

C




for> (i = 0; i fork();>

przewijanie myszy nie działa
>

>

Całkowita liczba utworzonych procesów potomnych wynosi (BRAMA-CS-2008)

(Jakiś
(B) 2^n – 1
(C) 2^n
(D) 2^(n+1) – 1

Zobacz to, aby znaleźć rozwiązanie.

2. Rozważ następujący fragment kodu:

C




if> (fork() == 0) {> >a = a + 5;> >printf>(>'%d, %d '>, a, &a);> }> else> {> >a = a –5;> >printf>(>'%d, %d '>, a, &a);> }>

>

>

Niech u, v będą wartościami drukowanymi przez proces nadrzędny, a x, y będą wartościami drukowanymi przez proces potomny. Które z poniższych jest PRAWDZIWE? (BRAMA-CS-2005)

(A) u = x + 10 i v = y
(B) u = x + 10 i v != y
(C) u + 10 = x i v = y
(D) u + 10 = x i v != y

Zobacz to, aby znaleźć rozwiązanie.

3. Przewiduj wynik działania poniższego programu.

C


zdjęcia z icloud na Androida



#include> #include> int> main()> > >fork();> >fork() && fork()>

>

>

Zobacz to, aby znaleźć rozwiązanie

Powiązane artykuły :

  • Program w C demonstrujący fork() i pipe()
  • Procesy zombie i sieroce w C
  • fork() i procesy współdzielone pamięci czarno-białej utworzone przy jego użyciu