Comprendre le mécanisme de la fourche dans Unix

J’essaie de comprendre le comportement des processus parent et enfant. Ci-dessous est mon code

#include  #include  #include  int main(void) { int i,j,cnt=0; int pid,present_pid; int a[10]; for(i=0; i<10; i++) { a[i] = i; } i = 0; j = 5; present_pid = getpid(); printf("Now in process %d\n",getpid()); printf("\n*******************before fork******************\n"); for(i=0;i<10;i++) { printf(" %d",a[i]); } printf("\n*******************before fork******************\n"); int ret = fork(); if(ret == 0) { printf("\n*******************after fork******************\n"); printf("Now in process %d\n",getpid()); printf("Child Process created"); for(i=0; i 0) { printf("\nNow in process %d\n",getpid()); for(j=5; j<10; j++) { a[j] = +1; j++; } wait(); } for(i=0;i<10;i++) { printf(" %d",a[i]); } return 0; } 

Ceci est la sortie du programme

 Now in process 12248 *******************before fork****************** 0 1 2 3 4 5 6 7 8 9 *******************before fork****************** *******************after fork****************** Now in process 12249 Child Process created 1 1 3 3 5 5 6 7 8 9 Now in process 12248 0 1 2 3 4 6 6 8 8 

Donc, au départ, il n’y a qu’un seul processus 12248 qui forge un autre processus (12249). Maintenant, le processus est parallèle (corrigez-moi si je me trompe). Idéalement, l’enfant devrait append 1 au contenu du tableau a seulement à la première moitié et le parent devrait faire la même chose pour la deuxième partie. Mais comme vous pouvez le voir, le résultat n’est pas celui attendu. S’il vous plaît donner des suggestions ..

Un processus créé par fork est un véritable processus OS lourd, pas seulement un thread léger! Le processus créé ne partage aucune mémoire avec le processus à partir duquel il a été créé. Au lieu de cela, la mémoire est copiée (paresseusement, appelée copie sur écriture), de sorte que vous avez en fait deux tableaux a maintenant et que chaque processus écrit sur sa propre copie de a .

il y a 2 petites erreurs dans votre code. Habituellement, nous ne remarquons même pas leur existence.

  1. a[i]= +1; Oh cher. Je suppose que vous voulez écrire a[i] += 1 ou a[i]++ .
  2. Redondant i++ et j++ . La boucle for a fait cela pour vous.

Corrigez-les et vous obtiendrez la réponse attendue.

Tout d’abord apporter quelques modifications à votre code

  printf("Now in process %d\n",getpid()); printf("Child Process created"); for(i=0; i<5; i++) { --> a[i]+= 1; --> // i++; //comment this line you are jumping 2 steps in this loop } 

Quant au concept de fork ()

Chaque fois que vous faites un appel fork (), la copie exacte de l’espace adresse du processus est créée pour le processus enfant et le compteur du programme est défini sur la ligne après l’appel à fork ().

Dans votre cas après cette ligne

  int ret = fork(); Program Counter--> if(ret == 0) { 

prochain,

 Now both the process run parallel 

Oui, le processus parent s’exécute en parallèle mais il attend le signal SIGCHLD du processus enfant une fois son exécution terminée.

Si le processus fils renvoie le signal SIGCHLD mais que le processus parent ne l’a pas encore reçu (c’est-à-dire que le processus parent est en attente), le processus fils s’appelle le processus ZOMBIE .

Si le processus parent est interrompu brusquement et que le processus enfant est toujours en cours d’exécution (ou en état READY ), le processus fils est appelé processus ORPHAN . Dans ce cas, le processus appelé init est responsable de la collecte du statut du processus enfant.

enfin, le programme se déroule. Le processus parent s’exécute initialement.

 int ret = fork();//A child process is created 

alors ce code s’exécute dans le processus enfant

  if(ret == 0) { printf("\n*******************after fork******************\n"); printf("Now in process %d\n",getpid()); printf("Child Process created"); for(i=0; i<5; i++) { a[i] += 1; //i++; } } else if(ret > 0)//this condition is false in child process { // rest of code } 

// et enfin c’est excédé

 for(i=0;i<10;i++) { printf(" %d",a[i]); } return 0; then child process returns SIGCHLD signal 

le code suivant est exécuté dans le processus parent

  else if(ret > 0)//this is true for parent process { printf("\nNow in process %d\n",getpid()); for(j=5; j<10; j++) { a[j] = +1; j++; } wait(); } for(i=0;i<10;i++) { printf(" %d",a[i]); } return 0; 

}

REMARQUE: le processus parent renvoie également le signal SIGCHLD et ce signal est collecté par le processus init .

Chaque fois qu'un nouveau processus est généré, il est par défaut un processus enfant du processus init .