Fork (Unix)

Ten artykuł dotyczy funkcji systemowej w systemie Unix. Zobacz też: fork jako nowy projekt będący odgałęzieniem już istniejącego projektu.

forkfunkcja systemowa w systemach operacyjnych Unix (i uniksopodobnych) powodująca, że proces wywołujący tę funkcję ulega w chwili jej wywołania podziałowi (albo „rozwidleniu”, ang. fork) na dwa procesy (innymi słowy – tworzony jest nowy proces). O jednym z tych procesów mówi się „proces-rodzic” (ang. parent process) a o drugim – „proces potomny” (lub czasem „potomek”, „proces-dziecko”, ang. child process)[1].

DziałanieEdytuj

W chwili utworzenia, proces-dziecko jest kopią procesu-rodzica (kopiowane są obszary pamięci, wartości zmiennych i część środowiska). Co więcej, po wywołaniu funkcji fork(), wykonywany jest dalej ten sam kod w przypadku zarówno procesu-rodzica i procesu-dziecka. Aby umożliwić zróżnicowanie dalszego działania obu procesów, konieczne jest ustalenie, który z nich jest dzieckiem, a który rodzicem. W tym celu testuje się wartość zwracaną przez funkcję fork() (która jest liczbą całkowitą).

Tu możliwe są trzy przypadki:

  • Jeśli wartość zwracana wynosi -1 oznacza to, że proces sprawdzający wartość zwracaną to proces-rodzic, ale nie udało się stworzyć procesu potomnego (dziecka),
  • Jeśli wartość zwracana wynosi 0 oznacza to, że proces sprawdzający wartość zwracaną to proces-dziecko,
  • Jeśli wartość zwracana jest liczbą dodatnią oznacza to, że proces sprawdzający wartość zwracaną to proces-rodzic, którego potomek ma identyfikator PID równy tej właśnie liczbie.

Podjęcie dalszych działań w procesie jest uzależnione od wartości wyniku. W treści programu, który uległ rozwidleniu zawarty jest zazwyczaj kod procesu-rodzica jak i procesu potomnego (lecz mogą działać wówczas inne procedury – np. proces-dziecko może być zależne w swoich działaniach od procesu rodzica).

W wielu przypadkach po wywołaniu funkcji fork() następuje szybkie wywołanie funkcji systemowej exec() (uruchamiającej nową aplikację).

PrzykładEdytuj

Fragment przykładowego kodu w C używającego funkcji fork():

 
switch(fork())
{
  case -1:
    //jesteśmy w rodzicu, ale operacja się nie udała
    break;
 
  case 0:
    //jesteśmy w dziecku
    break;

  default:
    //jesteśmy w rodzicu
    break;
}

DyskusjaEdytuj

Współcześnie w środowisku twórców systemów operacyjnych funkcja fork() uchodzi za funkcję z wielu względów niedoskonałą; stwierdza się np., że fork() powstał jako metoda prowizoryczna (ang. hack). Stąd pojawiają głosy, by funkcja została zastąpiona innymi mechanizmami zarządzania cyklem życia procesu[2].

PrzypisyEdytuj

  1. Stevens, W. Richard. Programowanie zastosowań sieciowych w systemie Unix. Wydawnictwa Naukowo-Techniczne, 1995
  2. Andrew Baumann, Jonathan Appavoo, Orran Krieger, and Timothy Roscoe. 2019. "A fork() in the road", Workshop on Hot Topics in Operating Systems (HotOS ’19), 13–15 maja, 2019, Bertinoro, Włochy. ACM, New York, NY, USA, 9 pages. https://doi.org/10.1145/3317550.3321435

Zobacz teżEdytuj