CSC 3102 – Introduction aux systèmes d’exploitation

Portail informatique

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.
pas d'image, désolé !

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" ]).

Modifiez votre script de façon à ce que le processus initial initialise et exporte la variable pidInitial. Pour vous assurer que votre programme est correct, modifiez aussi l'affichage « Processus X démarre », où X est le PID du processus courant, en « Processus X démarre avec le processus initial Y », où Y est le PID du processus initial. Testez votre programme en lançant ./chaine.sh 4.
$ ./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.