Fork System Call en C

Fork System Call C



L'appel système fork() est utilisé pour créer des processus enfants dans un programme C. fork() est utilisé lorsqu'un traitement parallèle est requis dans votre application. La fonction système fork() est définie dans les en-têtes sys/types.h et unistd.h . Dans un programme où vous utilisez fork, vous devez également utiliser l'appel système wait(). L'appel système wait() est utilisé pour attendre dans le processus parent que le processus enfant se termine. Pour terminer un processus enfant, l'appel système exit() est utilisé dans le processus enfant. La fonction wait() est définie dans l'en-tête sys/attendre.h et la fonction exit() est définie dans l'en-tête stdlib.h .

Fig 1 : Flux de travail de base de fork()

Fig 1 : Flux de travail de base de fork()







Dans cet article, je vais vous montrer comment utiliser l'appel système fork() pour créer des processus enfants en C. Alors, commençons.



fork() Syntaxe et valeur de retour :

La syntaxe de la fonction système fork() est la suivante :



fourche pid_t(annuler);

La fonction système fork() n'accepte aucun argument. Il renvoie un entier du type pid_t .





En cas de succès, fork() renvoie le PID du processus enfant qui est supérieur à 0. À l'intérieur du processus enfant, la valeur de retour est 0. Si fork() échoue, il renvoie -1.

Exemple simple de fork() :

Un exemple simple de fork() est donné ci-dessous :



#comprendre
#comprendre
#comprendre
#comprendre
#comprendre

entierprincipale(annuler) {
pid_t pid=fourchette();

si(pid== 0) {
imprimer ('Enfant => PPID : %d PID : %d ',getppid(),getpid());
sortir (EXIT_SUCCESS);
}
autre si(pid> 0) {
imprimer ('Parent => PID : %d ',getpid());
imprimer ('En attente de la fin du processus enfant. ');
attendre(NUL);
imprimer ('Processus enfant terminé. ');
}
autre {
imprimer ('Impossible de créer un processus enfant. ');
}

revenirEXIT_SUCCESS;
}

Ici, j'ai utilisé fork() pour créer un processus enfant à partir du processus principal/parent. Ensuite, j'ai imprimé le PID (ID de processus) et le PPID (ID de processus parent) à partir du processus enfant et parent. Sur le processus parent, wait(NULL) est utilisé pour attendre la fin du processus enfant. Sur le processus enfant, exit() est utilisé pour terminer le processus enfant. Comme vous pouvez le voir, le PID du processus parent est le PPID du processus enfant. Ainsi, le processus enfant 24738 appartient au processus parent 24731 .

Vous pouvez également utiliser des fonctions pour rendre votre programme plus modulaire. Ici, j'ai utilisé processusTâche() et parentTâche() fonctions pour les processus fils et parents respectivement. C'est ainsi que fork() est réellement utilisé.

#comprendre
#comprendre
#comprendre
#comprendre
#comprendre

annulerenfantTâche() {
imprimer ('Bonjour le monde ');
}

annulerparentTâche() {
imprimer ('Tâche principale. ');
}

entierprincipale(annuler) {
pid_t pid=fourchette();

si(pid== 0) {
enfantTâche();
sortir (EXIT_SUCCESS);
}
autre si(pid> 0) {
attendre(NUL);
parentTâche();
}
autre {
imprimer ('Impossible de créer un processus enfant.');
}

revenirEXIT_SUCCESS;
}

La sortie du programme ci-dessus :

Exécution de plusieurs processus enfants à l'aide de fork() et de Loop :

Vous pouvez également utiliser loop pour créer autant de processus enfants que nécessaire. Dans l'exemple ci-dessous, j'ai créé 5 processus enfants à l'aide de la boucle for. J'ai également imprimé le PID et le PPID des processus enfants.

#comprendre
#comprendre
#comprendre
#comprendre
#comprendre

entierprincipale(annuler) {
pour(entierje= 1;je<= 5;je++) {
pid_t pid=fourchette();

si(pid== 0) {
imprimer ('Processus enfant => PPID=%d, PID=%d ',getppid(),getpid());
sortir (0);
}
autre {
imprimer ('Processus parent => PID=%d ',getpid());
imprimer ('En attente de la fin des processus enfants... ');
attendre(NUL);
imprimer ('processus enfant terminé. ');
}
}

revenirEXIT_SUCCESS;
}

Comme vous pouvez le voir, l'ID du processus parent est le même dans tous les processus enfants. Ils appartiennent donc tous au même parent. Ils s'exécutent également de manière linéaire. L'un après l'autre. Le contrôle des processus enfants est une tâche complexe. Si vous en apprenez davantage sur la programmation système Linux et son fonctionnement, vous pourrez contrôler le flux de ces processus comme bon vous semble.

Exemple réel :

Différents calculs mathématiques complexes tels que la génération de hachage md5, sha256, etc. nécessitent beaucoup de puissance de traitement. Au lieu de calculer des choses comme ça dans le même processus que le programme principal, vous pouvez simplement calculer le hachage sur un processus enfant et renvoyer le hachage au processus principal.

Dans l'exemple suivant, j'ai généré un code PIN à 4 chiffres dans un processus enfant et l'ai envoyé au processus parent, le programme principal. Ensuite, j'ai imprimé le code PIN à partir de là.

#comprendre
#comprendre
#comprendre
#comprendre
#comprendre

entierobtenir le NIP() {
// utilise PPID et PID comme germe
srand (getpid() +getppid());
entiersecret= 1000 + ligne () % 9000;
revenirsecret;
}

entierprincipale(annuler) {
entierfd[2];
tuyau(fd);
pid_t pid=fourchette();

si(pid> 0) {
proche(0);
proche(fd[1]);
après(fd[0]);

entiernuméro secret;
taille_treadBytes=lire(fd[0], &numéro secret, taille de(numéro secret));

imprimer ('En attente du code PIN... ');
attendre(NUL);
imprimer ('Octets lus : %ld ',readBytes);
imprimer ('Code PIN : %d ',numéro secret);
}
autre si(pid== 0) {
proche(1);
proche(fd[0]);
après(fd[1]);

entiersecret=obtenir le NIP();
écrivez(fd[1], &secret, taille de(secret));
sortir (EXIT_SUCCESS);
}

revenirEXIT_SUCCESS;
}

Comme vous pouvez le voir, chaque fois que j'exécute le programme, je reçois un code PIN à 4 chiffres différent.

Donc, c'est essentiellement la façon dont vous utilisez l'appel système fork() sous Linux. Merci d'avoir lu cet article.