Confondu avec fork ()

J’ai du mal à comprendre ce que fait la commande fork () dans différents scénarios. Voici un exemple de code de mon livre:

int main() { int a = 12; int b = 9; int fid = fork(); if (fid == 0) { a++; } else { wait(NULL); b = b - 5; } printf("program exit. a = %d, b = %d\n", a, b); return 0; } 

Quelqu’un peut-il m’expliquer ce que la commande fork () fait dans ce cas et peut-être donner quelques exemples supplémentaires pour clarifier?

  [main] a = 12 b = 9 fork() | | +--------------+--------------+ | | | | [parent] [child] fid = 1234 fid = 0 wait(NULL) a++ ... printf("a = 13, b = 9"); ... return 0 ...  b = b - 5 printf("a = 12, b = 4"); return 0  

Après l’exécution de fork() il existe deux copies du programme. Chaque processus obtient ses propres copies des variables, il y a donc deux a , deux b , etc. La seule différence entre les deux programmes est la valeur renvoyée par fork() : dans le processus enfant, fork() renvoie 0; dans le processus parent, il renvoie le PID de l’enfant.

Le processus enfant incrémente a , imprime les valeurs de a et b et se termine.

Le processus parent attend d’abord la fin du processus enfant. Une fois que l’enfant a terminé, il continue, en soustrayant 5 de b , en imprimant a et b , puis en sortant.

L’ wait(NULL) garantit que l’impression du processus enfant vient toujours avant celle du parent, de sorte que vous obtiendrez toujours la même sortie dans un ordre fiable. Sans cela, vous ne pourriez pas dépendre de l’ordre des deux impressions. Ce sont les mêmes messages, dans un ordre imprévisible.

  1. a est défini sur 12, b est défini sur 9.

  2. fork s’appelle, nous avons maintenant deux processus.

  3. Le parent obtient le PID de l’enfant et passe à la clause else . L’enfant obtient 0 et passe à la clause if .

  4. Le parent attend que l’enfant ait fini.

  5. L’enfant incrémente sa copie de a . Donc, a est maintenant 13 dans l’enfant et 12 dans le parent.

  6. L’enfant quitte, en produisant 13 et 9 .

  7. Le parent soustrait 5 de sa copie de b , b est donc 4 dans le parent.

  8. Le parent quitte en affichant 12 et 4 .

Notez que l’ordre exact d’exécution des enfants et des parents après la fork n’est pas garanti, mais ne modifie pas les résultats, car le parent attend que l’enfant termine avant de faire quoi que ce soit.

Notez également que le fait de quitter normalement les deux processus est une mauvaise pratique. Lorsqu’un processus se termine normalement, il exécute des gestionnaires de nettoyage pouvant perturber l’autre processus, par exemple en modifiant la position du fichier sur les descriptions de fichier partagées, ce qui entraîne une corruption des données.

Lorsque vous appelez fork() , l’ensemble du processus, y compris la mémoire / les variables, etc., est dupliqué.

Ainsi, après l’appel fork , chaque processus a sa propre copie de a et b qui commencent respectivement par 12 et 9 .

Processus 0, incrémentera sa propre copie de a . Le processus 1 décrémentera (par 5) sa propre copie de b .

Donc, ils devraient imprimer:

 Process 0: a = 13, b = 9 Process 1: a = 12, b = 4 

Son o / p serait Parent :: a = 12, b = 4 Enfant :: a = 13, b = 9

comme les deux processus s’exécutent simultanément mais que les deux copies sont différentes des variables locales a, b donc locale var. affectés par un processus ne seront pas visibles par un autre processus car les deux travaillent sur leur propre copie