Bonjour une petite question sur les fork.
La condition du if n 'est jamais vraie ?Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 int main() { int p1,p2,p3; p1=fork(); p2=fork(); if(p2==0) p3=fork(); exit(0); }
ou je n ai pas compris les fork
Merci
Version imprimable
Bonjour une petite question sur les fork.
La condition du if n 'est jamais vraie ?Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 int main() { int p1,p2,p3; p1=fork(); p2=fork(); if(p2==0) p3=fork(); exit(0); }
ou je n ai pas compris les fork
Merci
Le pid sera de 0 dans le processus fils forké.
Merci pour la reponse il faut que je revois ca alors h8O
Plus exactement, le pid sera de 0 dans les processus 'forkés'.
Le père à un fils au moment du p1 = fork();.
Le père et son fils ont chacun un petit-fils au moment du p2 = fork();.
Et les deux petit-fils produits auront un fils au moment du p3 = fork();.
D'où 6 processus dont seulement 2 auront p2 != 0.
Bonjour
Ca semble compliqué au premier abord mais en réalité ça reste simple (mais avec ton exemple où tu fais deux fork, forcément là ça complexifie vachement !!!)
Ce qu'il faut bien comprendre dès le début, c'est que dès que tu appelles fork(), l'OS dédouble ton processus. Avant le fork() il n'y a qu'un processus, après le fork() il y en a deux. Et à partir de là, tout ce qui suit est alors exécuté par les deux.
Exemple
Si tu compiles et exécutes, tu auras une fois "Avant" et deux fois "Après" parce que ce second affichage aura été fait par deux processus (et que les deux écrivent à l'écran).Code:
1
2
3
4
5 int main() { printf("Avant\n"); fork(); printf("Après\n"); }
Autre exemple
Là tu auras une fois "Avant" avec un chiffre représentant le n° de processus en cours, et deux fois après avec l'un des deux ayant le même chiffre (c'est toujours le même processus) et l'autre ayant un chiffre différent (on peut estimer qu'il sera égal au premier incrémenté de 1) parce qu'il s'agit d'un nouveau processus généré par le fork(). On dit alors que le second est le "fils" du premier, qui, lui, est alors le "père" du second.Code:
1
2
3
4
5 int main() { printf("Avant %d\n", getpid()); fork(); printf("Après %d\n", getpid()); }
L'intérêt de générer un autre processus toutefois de pouvoir lui faire faire des trucs en collaboration avec le premier et non des trucs identiques. Pour ce, il faut alors arriver à les distinguer l'un de l'autre.
Ben cette distinction est faite dans le retour lui-même du fork(). Dans le processus fils ce retour vaut 0, et dans le père il vaut le n° du fils généré.
Ainsi, en testant ce retour, on peut alors distinguer les deux cas
Code:
1
2
3
4
5
6
7
8 int main() { int p; printf("Avant %d\n", getpid); if ((p=fork()) == 0) printf("Je suis le fils %d\n", getpid()); else printf("Je suis le père %d de %d\n", p, getpid()); }
Attention, ce n'est pas parce qu'on a testé les deux cas qu'il faut oublier que tout ce qui suit reste soumis au doublon.
Dans ce 4° exemple, le "Après" sera affiché par les deux processus qui continuent à exister et ce, jusqu'à la fin du programme ou bien jusqu'à la mort demandée (et vaut mieux la demander dans le fils car si c'est le père qui meurt ça devient assez bordelique à récupérer ensuite)Code:
1
2
3
4
5
6
7
8
9 int main() { int p; printf("Avant %d\n", getpid); if ((p=fork()) == 0) printf("Je suis le fils %d\n", getpid()); else printf("Je suis le père %d de %d\n", p, getpid()); printf("Après %d\n", getpid()); }
Donc ici, le fils demande à mourir dans la partie du code qui lui est propre. L'OS obéit à sa requête et l'arrête mais le père, lui, (qui n'a alors plus besoin de else) continue son travail jusqu'à la fin du programme.Code:
1
2
3
4
5
6
7
8
9
10 int main() { int p; printf("Avant %d\n", getpid); if ((p=fork()) == 0) { printf("Je suis le fils %d\n", getpid()); exit(0); } printf("Je suis le père %d de %d\n", p, getpid()); printf("Après %d\n", getpid()); }
Toi, avec ton exemple, tu as un processus P1 qui génère un P2 avec le premier fork(). Ensuite, P1 génère P3 et P2 génère P4 (second fork() exécuté par P1 et P2). Et enfin P3 et P4 seuls (car dans le cas "fils" du second fork()) appellent le 3° fork() donc P3 génère P5 et P4 génère P6.
Et si on fait l'arbre, alors
P1_P2_P4_P6
|__P3_P5
Comme le chat de Schrödinger qui est à la fois vivant et mort, la condition est à la fois vraie et à la fois pas vraie.
Il s'y ajoute des facéties liées à la présence de tampons
Code:
1
2
3 printf("a"); fork(); printf("b\n");
Si la chaine "a" est restée dans le tampon d'écriture avant le fork(), comme le tampon est dédoublé lors du fork(), "ab" s'affichera deux fois. Chacun son tampon.
Précaution : fflush(stdout); avant le fork().
Si la question est "est-ce que fork() retourne 0 ?", la réponse est une autre question : "retourne à qui ?".