8. fork, exec, wait et création de processus
8.1 Arborescence Unix
Sous Unix/Linux, un processus peut créer des fils, qui peuvent eux-mêmes créer des descendants. Les processus forment donc une arborescence. Le modèle classique présente init comme PID 1; sur les distributions modernes, ce rôle est souvent assuré par systemd.
8.2 fork()
fork() crée un fils à partir du processus courant. Après l'appel, père et fils poursuivent tous deux à l'instruction suivante, dans des espaces logiques indépendants.
Code (c) · sélectionner pour copier
pid_t pid = fork();
if (pid < 0) {
/* échec */
} else if (pid == 0) {
/* fils */
} else {
/* père : pid est le PID du fils */
}
La valeur de retour distingue les branches :
- négative : échec;
0dans le fils;- PID du fils, donc valeur positive, dans le père.
Le noyau attribue le PID et prépare les structures du fils. Conceptuellement, le fils reçoit une copie de l'environnement du père; les systèmes modernes évitent généralement une copie physique immédiate de toutes les pages grâce à des optimisations comme la copie sur écriture.
Le père et le fils sont concurrents. Sans synchronisation, leur ordre d'affichage n'est pas garanti et peut varier entre deux exécutions.
8.3 exec*()
La famille exec ne crée pas de processus. Elle remplace le code, les données, le tas et la pile du processus courant par un autre programme, tout en conservant son PID.
- Les variantes
execl*reçoivent une liste d'arguments. - Les variantes
execv*reçoivent un tableau. - Les formes contenant
precherchent l'exécutable dansPATH. - Certaines formes reçoivent explicitement l'environnement.
Un exec réussi ne retourne pas à l'ancien programme. Un retour indique normalement une erreur.
Le patron du shell est : fork() pour créer un fils, exec() dans le fils pour charger la commande, puis attente éventuelle du père.
8.4 wait() et waitpid()
wait() suspend le père jusqu'à la terminaison d'un de ses fils et permet de récupérer son PID et son statut. Une boucle est nécessaire pour attendre plusieurs enfants. waitpid() vise un enfant déterminé et accepte des options supplémentaires.
L'attente impose un ordre causal et permet au système de libérer complètement les informations conservées sur le fils terminé. Elle ne doit pas être confondue avec une pause arbitraire comme sleep().
8.5 Comparaison avec Windows
Sous Windows, CreateProcess crée un processus indépendant et son thread principal, puis retourne leurs identifiants et handles dans PROCESS_INFORMATION. Le créateur peut attendre la terminaison et doit fermer les handles reçus. Cette interface réunit création du processus et lancement de l'image exécutable, là où le modèle Unix sépare habituellement fork() et exec().