Chaîne de processus (∼1h15)
Cet exercice a pour but de vous apprendre à créer plusieurs processus
en utilisant un algorithme récursif.
Comme présenté sur la figure qui suit, vous allez créer une chaîne de N processus.
Dans une chaîne de processus, chaque processus est le père du suivant,
sauf pour le dernier processus de la chaîne, qui lui, n'a pas de fils.
Le premier processus de la chaîne est appelé le processus initial et le
dernier le processus final.
Les autres processus sont appelés les processus intermédiaires.
L'algorithme que nous utilisons est récursif.
Si N vaut 1, alors l'unique processus de la chaîne est le processus final.
Il ne doit donc rien faire de spécial.
Si N est strictement supérieur à 1, alors le processus doit encore créer N-1 processus.
Pour cela, il lui suffit de lancer chaine.sh avec comme paramètre N-1.
Nous allons écrire le script qui crée une chaîne de processus étape par étape.
Pour commencer, écrivez un script nommé chaine.sh qui :
- Vérifie ses arguments. Si le script ne reçoit pas un unique argument, il doit quitter avec un message d'erreur et un code de retour faux.
- Affiche le message « Processus X démarre », où X est le PID du processus.
- Quitte avec un code de retour vrai.
Avant de créer récursivement les processus, dans cette question, nous affichons
ce que l'algorithme est supposé faire.
Modifier votre script de façon à ce que :
- si N est strictement supérieur à 1, votre script affiche « Il reste K processus à créer », où K est égal à N-1,
- sinon, votre script affiche « Fin de chaîne ».
Nous finalisons maintenant l'algorithme.
Après avoir affiché
« Il reste K processus à créer », où K=N-1, votre
script doit donc lancer la commande ./chaine.sh K
pour créer le processus suivant de la chaîne.
Vérifiez que vous démarrez bien 4 processus lorsque vous invoquez
./chaine.sh 4.
$ chaine.sh 4
Processus 41732 démarre
Il reste 3 processus à créer
Processus 41734 démarre
Il reste 2 processus à créer
Processus 41736 démarre
Il reste 1 processus à créer
Processus 41738 démarre
Fin de chaîne
Il faut maintenant lancer les processus en tâche de fond.
Un processus ne doit aussi se terminer que lorsque son fils direct est terminé.
Enfin, tous les processus (y compris le processus final)
doivent afficher Processus X termine, où X
est le PID du processus courant.
Pour les processus qui possèdent un fils, cet affichage
doit avoir lieu après avoir attendu la fin du fils.
Modifiez votre script en conséquence. Vérifiez aussi que les messages
de terminaison s'affichent dans l'ordre inverse des créations en lançant
./chaine.sh 4.
$ ./chaine.sh 4
Processus 41929 démarre
Il reste 3 processus à créer
Processus 41931 démarre
Il reste 2 processus à créer
Processus 41933 démarre
Il reste 1 processus à créer
Processus 41935 démarre
Fin de chaîne
Processus 41935 termine
Processus 41933 termine
Processus 41931 termine
Processus 41929 termine
Nous souhaitons maintenant communiquer le PID du processus initial jusqu'au processus final.
Le langage bash fournit un mécanisme pour connaître le PID
de son parent direct, mais pas de ses autres aïeuls.
Il faut donc communiquer ce PID via un nouveau mécanisme.
Pour mettre en œuvre un tel mécanisme, nous devons résoudre deux sous-problèmes :
- Il faut être capable de communiquer le PID du processus initial jusqu'au processus final. Pour cela, nous utilisons une variable nommée pidInitial, initialisée par le processus initial à son PID, et exportée jusqu'au processus final.
- Il faut que le processus initial soit capable de se reconnaître de façon à initialiser et exporter cette variable pidInitial. Tous les processus, sauf le processus initial, vont démarrer avec une copie de la variable pidInitial puisque cette dernière est exportée par le processus initial. Le processus initial est donc l'unique processus pour lequel la variable pidInitial n'est pas définie initialement, c.-à-d., pour lequel la variable pidInitial a pour valeur la chaîne de caractère vide, qui se reconnaît avec la construction [ -z "$pidInitial" ]).
$ ./chaine.sh 4
Processus 42814 démarre avec le processus initial 42814
Il reste 3 processus à créer
Processus 42816 démarre avec le processus initial 42814
Il reste 2 processus à créer
Processus 42818 démarre avec le processus initial 42814
Il reste 1 processus à créer
Processus 42820 démarre avec le processus initial 42814
Fin de chaîne
Processus 42820 termine
Processus 42818 termine
Processus 42816 termine
Processus 42814 termine
Félicitation ! Vous venez d'écrire votre première application multi-processus complexe !
Mettez le script chaine.sh de côté, vous vous en servirez à la prochaine séance.
Mettez le script chaine.sh de côté, vous vous en servirez à la prochaine séance.