Exercices¶
- Dans quels cas l’appel système fork(2) peut-il retourner une erreur? Pourriez-vous construire un programme dans lequel fork(2) retourne une erreur ?
- Dans quels cas l’appel système wait(2) peut-il retourner une erreur ? Pourriez-vous écrire un petit programme dans lequel wait(2) retourne une erreur ?
- L’appel système fork(2) retourne l’identifiant du processus fils dans le processus père. Imaginez qu’une variante de Unix choisisse d’implémenter fork(2) en retournant
0
dans le processus fils et1
dans le processus père. Quel serait l’impact de cette modification pour un programme qui lance plusieurs processus fils ?
- Combien de processus sont créés lors de l’exécution du programme ci-dessous ?
// ... fork(); fork(); // ...
- En supposant que le processus père a comme identifiant la valeur
1252
, représentez graphiquement sous forme d’un arbre l’ensemble des processus créés par le programme ci-dessus en supposant que les identifiants de processus sont attribués séquentiellement par le kernel. - L’appel système fork(2) est nécessaire au fonctionnement de Unix. Cependant, un programme qui abuse de fork(2) risque de perturber le fonctionnement du système. Que risque-t-il d’arriver si vous exécutez un programme qui par mégarde contient :
while(true) {
fork();
// ...
}
Consultez les pages de manuel pour déterminer comment le système d’exploitation peut se protéger contre de telles fork bomb.
- Comparez les performances de la création et la terminaison de threads et de processus en compilant et exécutant sur un ordinateur non chargé les programmes
/Programmes/src/fork-perf.c
et/Programmes/src/pthread-perf.c
. Utilisez la commande time(1posix) pour mesurer le temps d’exécution de chacun des ces programmes qui créent 100000 processus ou threads. Expliquez vos résultats.
- Compilez le programme
/Programmes/src/fork-zombie.c
. Ce programme crée un processus mais le processus père attend une minute pour récupérer sa valeur de retour. Lancez ce programme en tâche de fond (voir section outils) et utilisez ps(1) ou consultez/proc/
- La librairie standard comprend une fonction system(3posix) qui permet l’exécution d’une commande du shell. Ainsi, la ligne
system("for f in {1..3} ; do echo $f ; done")
va provoquer un appel au shell bash(1) qui va exécuter la commande passé en argument et donc afficher trois lignes contenant chacune un nombre sur la sortie standard. Quels sont les appels systèmes utilisées par une implémentation de cette fonction system(3posix) ? - Quelles différences et similitudes voyez-vous entre :
- La commande strace(1) permet de tracer tous les appels systèmes faits par un programme. Recompilez un programme d’exemple et essayer d’identifier les principaux appels systèmes qui sont utilisés par ce programme. Les paramètres
-c
,-t
et-e
peuvent être utiles pour explorer le comportement d’un programme et avoir une idée des appels systèmes qu’il effectue. - La commande pstree(1) permet de visualiser sous forme d’arbre l’ensemble des processus actifs sur un ordinateur Linux. Exécutez pstree(1) et identifiez quels sont les processus qui sont les ancêtres de votre commande.
- Un shell tel que bash(1) permet à l’utilisateur de lancer plusieurs programmes simultanément. Par exemple, il est possible de lancer un programme en background (ou tâche de fond en français) en le suffixant avec le caractère
&
. On peut faire de même en tapant Ctrl-Z (les touches Ctrl et Z simultanément) pendant qu’un programme s’exécute. Cela peut être utile pour taper une commande pour par exemple voir l’état du système pendant l’exécution du programme. Il est possible de revenir à l’exécution du programme via la commande fg(1). La commande jobs(1posix) permet de lister les processus qui sont actuellement exécutés par le shell en tâche de fond. La section JOB CONTROL du manuel de bash(1) fournit plus d’informations à ce sujet. - Le répertoire
/proc
contient une image de la table des processus maintenue par le kernel et d’autres structures de données maintenues par le kernel. Compilez le programme/Programmes/src/fork-pthread.c
qui lance un processus fils puis crée un thread à l’intérieur du processus père. Lancez ce programme en background via bash(1) et observez les entrées relatives au père, au fils et au thread créé par le processus père dans/proc
. - Faites l’exercice sur les shell sur IngiNIOUS