Fork systeemoproep in C

Fork System Call C



fork() systeemaanroep wordt gebruikt om onderliggende processen in een C-programma te maken. fork() wordt gebruikt waar parallelle verwerking vereist is in uw toepassing. De systeemfunctie fork() is gedefinieerd in de headers sys/types.h en unistd.h . In een programma waarin je fork gebruikt, moet je ook wait() system call gebruiken. wait() systeemaanroep wordt gebruikt om in het bovenliggende proces te wachten totdat het onderliggende proces is voltooid. Om een ​​kindproces te beëindigen, wordt de systeemaanroep exit() gebruikt in het onderliggende proces. De functie wait() is gedefinieerd in de header sys/wait.h en de exit() functie is gedefinieerd in de header stdlib.h .

Fig 1: Basis fork() workflow

Fig 1: Basis fork() workflow







In dit artikel laat ik je zien hoe je de systeemaanroep fork() gebruikt om onderliggende processen in C te maken. Laten we beginnen.



fork() Syntaxis en retourwaarde:

De syntaxis van de systeemfunctie fork() is als volgt:



pid_t vork(leegte);

De systeemfunctie fork() accepteert geen enkel argument. Het retourneert een geheel getal van het type pid_t .





Bij succes retourneert fork() de PID van het onderliggende proces die groter is dan 0. Binnen het onderliggende proces is de geretourneerde waarde 0. Als fork() mislukt, retourneert het -1.

Eenvoudige fork() Voorbeeld:

Een eenvoudig fork()-voorbeeld wordt hieronder gegeven:



#erbij betrekken
#erbij betrekken
#erbij betrekken
#erbij betrekken
#erbij betrekken

inthoofd(leegte) {
pid_t pid=vork();

indien(pid== 0) {
printf ('Kind => PPID: %d PID: %dN',getppid(),getpid());
Uitgang (EXIT_SUCCESS);
}
anders indien(pid> 0) {
printf ('Ouder => PID: %dN',getpid());
printf ('Wachten tot het kindproces is voltooid.N');
wacht(NUL);
printf ('Kindproces afgerond.N');
}
anders {
printf ('Kan het onderliggende proces niet maken.N');
}

opbrengstEXIT_SUCCESS;
}

Hier heb ik fork() gebruikt om een ​​kindproces te maken van het hoofd-/ouderproces. Vervolgens heb ik de PID (proces-ID) en PPID (ouderproces-ID) van het kind- en ouderproces afgedrukt. Op het bovenliggende proces wordt wait (NULL) gebruikt om te wachten tot het onderliggende proces is voltooid. Op het onderliggende proces wordt exit() gebruikt om het onderliggende proces te voltooien. Zoals u kunt zien, is de PID van het bovenliggende proces de PPID van het onderliggende proces. Dus het kindproces 24738 behoort tot het bovenliggende proces 24731 .

U kunt ook functies gebruiken om uw programma modulair te maken. Hier, ik gebruikte procesTaak() en ouderTaak() functies voor respectievelijk de onderliggende en bovenliggende processen. Dit is hoe fork() daadwerkelijk wordt gebruikt.

#erbij betrekken
#erbij betrekken
#erbij betrekken
#erbij betrekken
#erbij betrekken

leegtechildTask() {
printf ('Hallo WereldN');
}

leegteouderTaak() {
printf ('Hoofdtaak.N');
}

inthoofd(leegte) {
pid_t pid=vork();

indien(pid== 0) {
childTask();
Uitgang (EXIT_SUCCESS);
}
anders indien(pid> 0) {
wacht(NUL);
ouderTaak();
}
anders {
printf ('Kan onderliggend proces niet maken.');
}

opbrengstEXIT_SUCCESS;
}

De output van het bovenstaande programma:

Meerdere onderliggende processen uitvoeren met fork() en Loop:

U kunt lus ook gebruiken om zoveel onderliggende processen te maken als u nodig hebt. In het onderstaande voorbeeld heb ik 5 onderliggende processen gemaakt met de for-lus. Ik heb ook de PID en PPID van de onderliggende processen afgedrukt.

#erbij betrekken
#erbij betrekken
#erbij betrekken
#erbij betrekken
#erbij betrekken

inthoofd(leegte) {
voor(intl= 1;l<= 5;l++) {
pid_t pid=vork();

indien(pid== 0) {
printf ('Kindproces => PPID=%d, PID=%dN',getppid(),getpid());
Uitgang (0);
}
anders {
printf ('Ouder proces => PID=%dN',getpid());
printf ('Wachten tot onderliggende processen zijn voltooid...N');
wacht(NUL);
printf ('kinderproces afgerond.N');
}
}

opbrengstEXIT_SUCCESS;
}

Zoals u kunt zien, is de bovenliggende proces-ID hetzelfde in alle onderliggende processen. Ze behoren dus allemaal tot dezelfde ouder. Ze worden ook lineair uitgevoerd. De een na de ander. Het beheersen van onderliggende processen is een ingewikkelde taak. Als je meer leert over Linux-systeemprogrammering en hoe het werkt, kun je de stroom van deze processen besturen zoals je wilt.

Voorbeeld uit het echte leven:

Verschillende complexe wiskundige berekeningen zoals md5, sha256 enz. Hash-generatie vereist veel verwerkingskracht. In plaats van dat soort dingen in hetzelfde proces als het hoofdprogramma te berekenen, kun je gewoon de hash van een onderliggend proces berekenen en de hash teruggeven aan het hoofdproces.

In het volgende voorbeeld heb ik een 4-cijferige pincode gegenereerd in een kindproces en deze naar het bovenliggende proces, het hoofdprogramma, gestuurd. Daarna heb ik de pincode vanaf daar afgedrukt.

#erbij betrekken
#erbij betrekken
#erbij betrekken
#erbij betrekken
#erbij betrekken

intgetPIN() {
// gebruik PPID en PID als het zaad
srand (getpid() +getppid());
intgeheim= 1000 + rij () % 9000;
opbrengstgeheim;
}

inthoofd(leegte) {
intfd[2];
pijp(fd);
pid_t pid=vork();

indien(pid> 0) {
dichtbij(0);
dichtbij(fd[1]);
na(fd[0]);

intgeheim nummer;
size_tleesBytes=lezen(fd[0], &geheim nummer, De grootte van(geheim nummer));

printf ('Wachten op pincode...N');
wacht(NUL);
printf ('Gelezen bytes: %ldN',leesBytes);
printf ('PIN: %dN',geheim nummer);
}
anders indien(pid== 0) {
dichtbij(1);
dichtbij(fd[0]);
na(fd[1]);

intgeheim=getPIN();
schrijven(fd[1], &geheim, De grootte van(geheim));
Uitgang (EXIT_SUCCESS);
}

opbrengstEXIT_SUCCESS;
}

Zoals je kunt zien, krijg ik elke keer dat ik het programma start een andere 4-cijferige pincode.

Dus dat is eigenlijk hoe je fork () systeemaanroep in Linux gebruikt. Bedankt voor het lezen van dit artikel.