fork()
»a
, 7 processus sont ensuite créés (on
ne compte pas ici le processus de départ lui-même, sinon la réponse
est 8).exec()
ne créé pas de nouveau
processus mais recouvre le code du processus courant par le code contenu
dans le fichier donné en argument; ensuite l'exécution est transférée à la
fonction main()
de ce nouveau programme.La condition du while
est fausse lorsque le retour de l'appel
à fork()
s'effectue dans le père, ou qu'il s'effectue dans le
fils et que la variable i (avant son incrémentation) est égale
ou plus grande que N
. En sortie du while
on
affiche la valeur de la variable i.
Donc, le premier processus créé affiche 0
, son
fils 1
, son petit fils 2
, ainsi de suite jusqu'à
la génération N+1
. Les nombres de 0
à N+1
sont affichés dans le désordre car nous
ne pouvons faire aucune hypothèse sur l'ordonnancement des processus qui
sont ici en concurrence. Il est toutefois assez probable que l'ordre
effectif soit proche de l'ordre naturel défini sur les entiers.
Le point délicat est de bien voir que le plus grand entier généré est
bien N+1
. En effet, supposons que i, soit égale
à N-1
, le fork()
s'exécute, le fils réalise que
lacondition est vraie et incrémente la variable qui vaut
alors N
, un nouveau fork()
s'exécute et le fils
réalise que la condition est désormais fausse, mais son effet de bord est
d'incrémenter la variable qui vaut alors N+1
. Cette subtilité
n'est pas importante, le point crucial est d'affirmer que l'ordre n'est pas
garanti.
wait()
ou pas wait()
? Telle est la question »void fils(int n,void (*g)()) { int i; for (i=0; i<n; i++) if (fork()==0) { g(); exit(0); } }
On peut se poser la questiondes zombies (c'est vrai que ça fait peur)... Auquel cas le père pourrait s'écrire:
void fils(int n,void (*g)()) { int i; for (i=0; i<n; i++) if (fork()==0) { g(); exit(0); } for (i=0; i<n i++) wait(NULL); }
void fils(int n,void (*g)()) { int i; for (i=0; i<n; i++) if (fork()==0) { g(); exit(0); } else { wait(NULL); } }