Laboratoire 4 - fork et exec
L’objectif de ce laboratoire est de se familiariser avec l’utilisation des appels système fork
et exec
Mise en bouche
Écrire un programme fork0
effectuant les opérations suivantes, dans l’ordre :
- Afficher « Mon PID est
<pid>
! ». Pour obtenir le PID, utilisergetpid()
. - Appeler la fonction
fork()
. - Afficher « Je suis le
<père|fils>
et mon PID est<pid>
. »
Voici un exemple de résultat:
Mon PID est <22097>
Je suis le père et mon PID est <22097>
Je suis le fils et mon PID est <22098>
Multiple fils
-
Écrire un programme
famille
qui crée 10 processus fils. Chacun d’entre eux devra afficher « Je suis le numéro<1 à 10>
, mon PID est<pid>
et mon père est<pid>
! ». -
Reprendre le programme
famille
et modifiez-le de façon à ce que le processus père, après avoir lancé les 10 fils, attende une entrée de l’utilisateur. Utilisez la fonctiongetchar()
. À l’aide de la commandeps -a
, exécutée dans une autre fenêtre-terminal, listez vos processus : pourquoi les 10 fils sont-ils encore là, bien que leur exécution soit terminée ? S’agit-il de processus zombies ? -
Utiliser l’appel système
waitpid()
pour corriger le problème de la question précédente. Utiliser le man pour plus d’informations sur l’utilisation de cet appel système. Pour chaque processus fils terminant son exécution, dans le code du parent afficher « le processus No.<x>
, PID<y>
vient de terminer ».
Hiérarchie de processus
- Créer une version
pchaine
du programme précédent qui réalise une chaine den
processus, où le nombren
est fourni par l’utilisateur à l’exécution de la commande. Chacun des processus devra afficher « Je suis un fils, mon PID est<pid>
et mon père est<pid>
». Par chaine de processus, on entend un processus parent qui lancen
enfants.
Exemple (les PID peuvent varier entre chaque exécution du programme):
$ pchaine 2
Je suis le père, mon PID est <31393>
Je suis un fils, mon PID est <31394> et mon père est <31393>
Je suis un fils, mon PID est <31395> et mon père est <31393>
- Créer un programme
parbre
qui réalise un arbre den
processus. Chacun des processus devra afficher « Je suis un fils, mon PID est<pid>
et mon père est<pid>
».
$ parbre 2
Je suis le père, mon PID est <31396>
Je suis un fils, mon PID est <31397> et mon père est <31396>
Je suis un fils, mon PID est <31398> et mon père est <31397>
Programme mystère
Soit le programme mystere.c
suivant:
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
int main(void) {
// ICI
if (fork()*fork()) fork();
else fork() || fork();
// LÀ
return 0;
}
-
Combien de processus sont créés ?
-
Dessinez la hiérarchie des processus.
-
Modifiez le programme « LÀ » pour que chaque processus affiche qui il est et quel est son parent. (comparez avec les questions précédentes).
Attention à ce que vos parents affichés soient légitimes :)
-
Modifiez le programme « ICI » et « LÀ » de façon à ce que le programme affiche la hiérarchie des processus dans un format compatible avec graphviz. De façon à ce que :
./mystere | xdot -
fonctionne.
Note : pas besoin d’être sophistiqué, la sortie suivante est très acceptable:
digraph {
rankdir = BT
1898331 -> 1898328
1898328 -> 1898327
1898327 -> 1486829
}
Recouvrement
-
Fonctions utiles:
getenv
,strtok
-
Exécuter la commande
exec ps
dans un terminal. Que se passe-t-il et pourquoi ? Vérifier votre explication avec l’utilisation deexec sh
et de la commandeps
. -
Écrire un programme
exec0
qui permet d’exécuter une commande qui lui est passée en argument. Exempleexec0 ps
. Pour ce faire, utiliser la fonctionexeclp
. -
Reprendre le programme
exec0
et remplacer l’utilisation deexeclp
parexecvp
afin d’exécuter la commande avec des arguments. Exempleexec0 ps -l
-
Reprendre le programme
exec0
pour qu’une fois l’exécution de la commande terminée, le programme affiche “L’exécution de la commande est terminée”. -
Bonus Reprendre le programme
exec0
et remplacer l’utilisation deexecvp
parexecv
. Pour que cela fonctionne il est nécessaire de trouver le chemin du programme que l’utilisateur a fourni en argument. Utiliser la variable d’environnementPATH
qui contient l’ensemble des répertoires où rechercher des programmes exécutables (la fonctiongetenv
vous sera utile). -
Bonus Écrire un programme
exec5
qui se recouvre exactement 5 fois, en affichant “Je suis le recouvrement <numéro de recouvrement>.”. Vous devez utiliser uniquement les fonctionsexec
(execl
,execlp
,execle
…).