Fork (informatica)
Een fork is een concept uit de informatica waarmee bedoeld wordt dat een proces een kopie van zichzelf maakt.
Wanneer een programma een nieuw proces wil starten dat gelijktijdig (ook wel parallel of concurrent genoemd) uitgevoerd wordt met het proces van het programma zelf, kan het het besturingssysteem door middel van de systeemaanroep fork() de opdracht geven een fork uit te voeren.
Het besturingssysteem creëert vervolgens een nieuw proces dat een exacte kopie is van het proces dat opdracht gaf een fork uit te voeren, inclusief de programmacode, de (inhoud van) de variabelen en de inhoud van de geheugensegmenten die bij het programma horen. Het enige verschil is dat het nieuw proces een andere process identifier (PID) heeft.
Het nieuw proces (het kindproces) wordt nu meteen gestart en begint met de eerstvolgende instructie na de fork. Ook het originele proces (het ouderproces) gaat verder met de uitvoering en natuurlijk ook met de eerstvolgende instructie na de fork. Er lopen nu dus twee vrijwel identieke processen die alleen een andere PID hebben.
Omdat beide processen dezelfde programmacode gebruiken, namelijk die van het originele proces dat de fork uitvoerde, moet deze programmacode zowel de functionaliteit van het ouderproces als die van het kindproces bevatten. Welke van de twee uitgevoerd moet worden, wordt bepaald aan de hand van de returnwaarde van fork(): in het kindproces geeft fork() de waarde 0 terug als returnwaarde en in het ouderproces de PID van het nieuw gecreëerde proces (deze is altijd groter dan 0: het procesid 0 is gereserveerd voor het speciale init-proces dat tijdens het opstarten van het systeem gecreëerd wordt).
In vele gevallen wordt de fork echter gebruikt om een ander programma op te starten door middel van een exec call. De woorden fork en exec worden dan ook veelal in een adem genoemd.
Voorbeeld
[bewerken | brontekst bewerken]Het onderstaande C-programma gebruikt fork() om een nieuw proces te starten. In het ouderproces levert fork() een waarde groter dan 0 op en wordt lus A uitgevoerd, welke 10 keer "Ouderproces" print. In het kindproces levert fork() de waarde 0 op en wordt lus B uitgevoerd, welke 10 keer "Kindproces" op het scherm zet. Beide lussen wachten telkens een seconde tussen het printen.
#include <stdio.h>
#include <unistd.h>
int
main(void)
{
int i, pid;
pid = fork();
if (pid > 0)
{
// fork() leverde een PID > 0 op: dit is het ouderproces
printf("Processid van het kindproces: %d\n", pid);
for (i=0; i<10; i++)
{ // Lus A
sleep(1);
printf("Ouderproces: %d\n", i);
}
}
else
if (pid == 0) {
// fork() leverde een PID == 0 op: dit is het kindproces
for (i=0; i<10; i++)
{
// Lus B
sleep(1);
printf("Kindproces: %d\n", i);
}
}
else {
// fork() leverde een PID < 0 op: er is geen proces gecreëerd
printf("geen proces gemaakt; response: %d\n", pid);
}
}
Het ouderproces print ook de processid van het nieuwe kindproces. Merk op dat dit telkens een andere waarde is: we weten alleen dat deze altijd groter dan 0 zal zijn als er met succes een nieuw proces gestart is. Wanneer het om de een of andere reden niet mogelijk was een nieuw proces te starten levert fork() een returnwaarde kleiner dan 0 op.
Ondersteuning
[bewerken | brontekst bewerken]De fork-functionaliteit en de bijbehorende systeemaanroep is aanwezig in alle besturingssystemen van de Unix-familie, waaronder Linux, BSD en Mac OS X. Microsoft Windows heeft deze functionaliteit niet. Windows heeft uiteraard wel systeemaanroepen om nieuwe processen te creëren, maar deze leveren een 'nieuw' proces op en geen kopie van het originele proces. Dit is vergelijkbaar met de bovengenoemde combinatie van fork en exec op Unix-systemen.