Chiamata di sistema forcella in C

Chiamata di sistema forcella in C
La chiamata di sistema FORK () viene utilizzata per creare processi figlio in un programma C. FORK () viene utilizzato dove è richiesta l'elaborazione parallela nell'applicazione. La funzione di sistema fork () è definita nelle intestazioni sys/tipi.H E unistd.H. In un programma in cui usi la forcella, devi anche usare la chiamata di sistema Wait (). La chiamata di sistema Wait () viene utilizzata per aspettare nel processo genitore affinché il processo figlio possa finire. Per finire un processo figlio, la chiamata di sistema Exit () viene utilizzata nel processo figlio. La funzione wait () è definita nell'intestazione sys/wait.H e la funzione exit () è definita nell'intestazione stdlib.H.

Fig 1: Basic Fork () Flusso di lavoro

In questo articolo, ti mostrerò come utilizzare la chiamata di sistema fork () per creare processi di figlio in c. Quindi iniziamo.

Sintassi fork () e valore di restituzione:

La sintassi della funzione di sistema FORK () è la seguente:

fork pid_t (void);

La funzione di sistema fork () non accetta alcun argomento. Restituisce un numero intero del tipo pid_t.

Al successo, fork () restituisce il PID del processo figlio che è maggiore di 0. All'interno del processo figlio, il valore di ritorno è 0. Se il fork () non riesce, restituisce -1.

Esempio semplice fork ():

Di seguito è riportato un semplice esempio fork ():

#includere
#includere
#includere
#includere
#includere
int main (void)
pid_t pid = fork ();
if (pid == 0)
printf ("child => ppid: %d pid: %d \ n", getppid (), getpid ());
usit (exit_success);

else if (pid> 0)
printf ("parent => pid: %d \ n", getpid ());
printf ("Aspettando il processo del bambino.\N");
wait (null);
printf ("Processo figlio finito.\N");

altro
printf ("Impossibile creare il processo figlio.\N");

restituire exit_success;

Qui, ho usato fork () per creare un processo figlio dal processo principale/genitore. Quindi, ho stampato il PID (ID di processo) e PPID (ID processo genitore) dal processo figlio e genitore. Sul processo genitore Wait (NULL) viene utilizzato per aspettare che il processo figlio finisca. Nel processo del bambino, l'uscita () viene utilizzata per completare il processo del bambino. Come puoi vedere, il PID del processo genitore è il PPID del processo figlio. Quindi, il processo del bambino 24738 appartiene al processo genitore 24731.

Puoi anche utilizzare le funzioni per rendere il tuo programma più modulare. Qui, ho usato processTask () E parentesk () funzioni rispettivamente per i processi figlio e genitore. Ecco come viene effettivamente utilizzato il fork ().

#includere
#includere
#includere
#includere
#includere
void ChildTask ()
printf ("Hello world \ n");

void parentTask ()
printf ("Attività principale.\N");

int main (void)
pid_t pid = fork ();
if (pid == 0)
ChildTask ();
usit (exit_success);

else if (pid> 0)
wait (null);
parentTask ();

altro
printf ("Impossibile creare il processo figlio.");

restituire exit_success;

L'output del programma sopra:

Esecuzione di più processi figlio tramite fork () e loop:

Puoi anche usare loop per creare tutti i processi per bambini di cui hai bisogno. Nell'esempio seguente, ho creato 5 processi per bambini utilizzando per loop. Ho anche stampato il PID e il PPID dai processi figlio.

#includere
#includere
#includere
#includere
#includere
int main (void)
per (int i = 1; i <= 5; i++)
pid_t pid = fork ();
if (pid == 0)
printf ("figlio di figlio => ppid =%d, pid =%d \ n", getppid (), getpid ());
uscita (0);

altro
printf ("Processo genitore => pid =%d \ n", getpid ());
printf ("Aspettando i processi figlio che finiscono ... \ n");
wait (null);
printf ("Processo figlio finito.\N");


restituire exit_success;

Come puoi vedere, l'ID processo principale è lo stesso in tutti i processi figlio. Quindi, tutti appartengono allo stesso genitore. Eseguono anche in modo lineare. Uno dopo l'altro. Controllare i processi del bambino è un compito sofisticato. Se impari di più sulla programmazione del sistema Linux e su come funziona, sarai in grado di controllare il flusso di questi processi, comunque che ti piacciono.

Esempio di vita reale:

Diversi calcoli matematici complessi come MD5, Sha256 ecc. La generazione di hash richiede molta potenza di elaborazione. Invece di calcolare cose del genere nello stesso processo del programma principale, puoi semplicemente calcolare l'hash sul processo di figlio e restituire l'hash al processo principale.

Nell'esempio seguente, ho generato un codice PIN a 4 cifre in un processo figlio e l'ho inviato al processo genitore, il programma principale. Quindi, ho stampato il codice PIN da lì.

#includere
#includere
#includere
#includere
#includere
int getpin ()
// Usa PPID e PID come seme
srand (getpid () + getppid ());
int secret = 1000 + rand () % 9000;
segreto di ritorno;

int main (void)
int fd [2];
pipe (FD);
pid_t pid = fork ();
if (pid> 0)
chiudere (0);
chiudere (fd [1]);
dup (fd [0]);
int secretNumber;
size_t readBytes = read (fd [0] e secretNumber, sizeof (secretNumber));
printf ("in attesa di pin… \ n");
wait (null);
printf ("byte leggi: %ld \ n", readbytes);
printf ("pin: %d \ n", segreto);

else if (pid == 0)
chiudere (1);
chiudere (fd [0]);
dup (fd [1]);
int secret = getPin ();
Scrivi (fd [1], & segreto, sizeof (segreto));
usit (exit_success);

restituire exit_success;

Come puoi vedere, ogni volta che eseguo il programma, ricevo un codice PIN diverso a 4 cifre.

Quindi, è fondamentalmente il modo in cui usi la chiamata di sistema FORK () in Linux. Grazie per aver letto questo articolo.