:: Enseignements :: ESIPE :: INFO2 :: 2014-2015 :: Programmation système en C ::
| fork() exec() |
Exercice 1 - mise en route
Préparation : Ecrire un programme qui affiche bonjour, puis exécute un
fork (sans switch, ne gérez pas son code de retour), puis affiche au revoir. Aviez-vous prévu le résultat ?
Exercice 2 - Anne, ma soeur Anne, ne vois-tu rien venir ?
Écrire un programme effectuant les opérations suivantes, dans l'ordre :
- afficher "mon PID est <pid>" avec printf (sans retour à la ligne);
pour obtenir le PID: getpid()
- afficher "my PID is <pid>" avec write (toujours sans retour à la ligne)
- fork()
- afficher "je suis le <père|fils> et mon PID est <pid>" avec printf
(toujours pas de retour à la ligne)
- afficher "I am the <parent|child> process and my PID is" en utilisant write
(toujours pas de retour à la ligne)
- forcer l'affichage de tous ces messages, par exemple avec un puts("").
Comprenez-vous pourquoi l'affichage ne correspond pas tout à fait à ce qu'on attend ?
Exercice 3 - Et ça continue, encore et encore...
- Ecrire un programme qui lance l'execution d'un ls.
- Améliorer le programme afin qu'il lance un ls, puis un ps, puis un free.
Exercice 4 - Hit the road, Jack
- Positionner des variables d'environnement RUN_0, RUN_1, RUN_2...,
puis, écrire un programme les affichant les unes après les autres. Il faut utiliser la fonction
getenv() pour récupérer la valeur d'une variable. Le programme devra afficher toutes les
variables, jusqu'à ce qu'il y en ait une qui n'existe pas; par exemple s'il y a RUN_0,
RUN_1 et RUN_3, il ne faut afficher que la 0 et la 1 (comme la 2
n'existe pas, le programme doit s'arrêter).
- En utilisant fork() et execvp(), écrire un programme, qu'on appellera mrun,
qui exécute les programmes présents dans RUN_0, RUN_1, etc., avec
les arguments de la ligne de commande. Par exemple, si RUN_0=ls et RUN_1=cat, alors
la commande "mrun toto.c titi.c" devra faire la même chose que "ls toto.c titi.c ; cat toto.c titi.c".
Il faut attendre l'exécution d'une commande avant de lancer la suivante, en utilisant wait().
Exercice 5 - Accident de fourchette
- Question piège: écrivez un processus qui, grâce à l'appel système fork(), lance 20 processus
affichant chacun "je suis le numéro <1 à 20>, mon PID est <pid> et mon père est <pid>"
(utilisez write() sur ce coup-là). Réfléchissez bien avant de lancer votre programme (si vous ne
faites pas attention, vous allez planter votre PC - vous êtes prévenus).
- Une fois que le programme précédent marche correctement, modifiez-le de façon à ce que le processus
père, après avoir lancé les 20 fils, boucle indéfiniment (while (1) pause();). Avec la commande ps,
listez vos processus: pourquoi les 20 fils sont-ils encore là, bien que leur exécution soit terminée ?
- Utiliser l'appel système waitpid() pour corriger le problème de la question précédente.
Pour chaque processus fils terminant son exécution, afficher "le processus n°<x> de PID <y>
vient de terminer".
Exercice 6 - Faire-parts de décès
Lorsqu'un processus fils se termine, le système envoie un signal
SIGCHLD au processus père.
Reprendre l'exercice précédent, et utiliser un handler de signal pour notifier sur la sortie standard
de la terminaison des fils.
© Université de Marne-la-Vallée