Partie 4 - Processus¶
p4e1 - Premier fork¶
Écrivez un programme C qui :
Affiche « Avant le fork, pid = PID »
Crée un processus enfant avec
fork()Le parent affiche : « Je suis le parent, PID = X, mon enfant a le PID = Y »
L’enfant affiche : « Je suis l’enfant, PID = X, mon parent a le PID = Y » puis se termine avec
_exit(0)Le parent attend l’enfant avec
waitet récupère le status de fin de l’enfantLe parent affiche ensuite le code de retour de l’enfant (testez avec l’enfant qui fait un
_exit(0)ou_exit(1))
Résultat attendu :
$ gcc -std=c2x -Wall -Wextra -pedantic -g p4/p4e1.c && ./a.out
Avant le fork
Je suis le parent, PID = 12345, mon enfant a le PID = 12346
Je suis l'enfant, PID = 12346, mon parent a le PID = 12345
Parent: enfant terminé normalement, code retour = 0
p4e2 - Copy-on-Write et isolation mémoire¶
Créez un programme qui montre l’isolation mémoire entre processus :
Créez un entier
x = 4fork()un processus enfantL’enfant modifie
x = 2et dort 2 secondesLes deux affichent la valeur et l’adresse de
x(avec%p)
Résultat attendu :
$ gcc -std=c2x -Wall -Wextra -pedantic -g p4/p4e2.c && ./a.out
[parent] PID=12345 x=4 &x=0x7ffd055fdc60
[child] PID=12346, PPID=12345 x=2 &x=0x7ffd055fdc60
Les adresses sont identiques mais les valeurs diffèrent. Pourquoi ?
p4e3 - Fork + Exec simple¶
Écrire un programme qui :
fork()un enfantL’enfant exécute la commande
cat -n p4e3.c(voir exec). Siexecéchoue →perror("exec")puis ``_exit(1)``Le parent attend avec
waitpid()et affiche si l’enfant s’est bien terminé
Résultat attendu :
$ gcc -std=c2x -Wall -Wextra -pedantic -g p4/p4e3.c && ./a.out
... contenu de p4e3.c ...
Parent: enfant terminé (OK)
p4e4 - Intercepter SIGTERM et ignorer SIGINT¶
Programmer un handler via sigaction avec SA_RESTART qui :
Enregistre le numéro du dernier signal dans
volatile sig_atomic_t last_signalUtilise un drapeau
volatile sig_atomic_t stop = 0pour arrêter la boucleBoucle toutes les secondes pour afficher le PID du processus jusqu’à réception de
SIGTERMEn cas de réception d’un
SIGINTle programme ne doit pas s’arrêter (les^Caffichés ci-dessous représentent un appui surCtrl+Cqui ne fait rien)Affiche ensuite le numéro du signal et le nom du signal correspondant (avec
strsignal(last_signal))
Vous pouvez partir de l”exemple du cours pour avoir une base.
Résultat attendu :
$ gcc -std=c2x -Wall -Wextra -pedantic -g p4/p4e4.c && ./a.out
PID=420928
PID=420928
^CPID=420928
PID=420928
^CPID=420928
PID=420928
PID=420928
PID=420928
Signal reçu : 15 (Terminated)
Testez le programme en envoyant un signal avec la commande kill depuis un autre terminal.
p4e5 - Pipe unidirectionnel parent→enfant¶
Écrire un programme qui :
Crée un
pipe(fd)fork()un enfantLe parent écrit un message dans
fd[1], puis fermefd[1]L’enfant lit depuis
fd[0]et affiche, puis fermefd[0]Bien fermer les extrémités inutiles dans chaque processus
Résultat attendu :
$ gcc -std=c2x -Wall -Wextra -pedantic -g p4/p4e5.c && ./a.out
Enfant a reçu : Bonjour depuis le parent !
p4e6 - Ping-pong bidirectionnel avec deux pipes¶
Écrire un programme parent-enfant utilisant deux pipes :
Pipe P1 (parent → enfant)
Pipe P2 (enfant → parent)
Le parent envoie
ping#1, l’enfant lit et répondpong#1Répéter pour
Néchanges (ex: 5)Afficher chaque message envoyé/reçu
Résultat attendu :
$ gcc -std=c2x -Wall -Wextra -pedantic -g p4/p4e6.c && ./a.out
[Parent] Envoi: ping#1
[Enfant] Reçu: ping#1
[Enfant] Envoi: pong#1
[Parent] Reçu: pong#1
[Parent] Envoi: ping#2
...
p4e7 - FIFO (tube nommé) - Writer & Reader¶
Créer deux programmes séparés qui communiquent via FIFO :
Programme p4e7_writer.c :
Crée
mkfifo("canal", 0666)si besoin (gérerEEXIST)Ouvre
"canal"en écriture (O_WRONLY) - bloquant jusqu’à un lecteurEnvoie
"Hello FIFO\n"puis fermeSupprime la FIFO avec
unlink("canal")
Programme p4e7_reader.c :
Ouvre “canal” en lecture (
O_RDONLY) - bloquant jusqu’à un écrivainLit tout jusqu’à EOF et affiche
Ferme le descripteur
Test :
$ gcc p4/p4e7_reader.c -o reader && gcc p4/p4e7_writer.c -o writer
$ ./reader &
[1] 12345
$ ./writer
Hello FIFO
[1]+ Done
p4e8 - Mini-shell avec commandes simples et background¶
Écrire un mini-shell qui :
Affiche un prompt
mini-shell>Lit une ligne de commande (avec
fgets)Parse les arguments (séparateur espace simple)
Lance les commandes dans un fork
fork + execvppuiswaitpidsur l’enfantCommande interne
exitpour quitter le shell
Vous pouvez vous aider de ce tutoriel : https://brennan.io/2015/01/16/write-a-shell-in-c/
Résultat attendu :
$ gcc -std=c2x -Wall -Wextra -pedantic -g p4/p4e8.c && ./a.out
mini-shell> echo hello
hello
mini-shell> sleep 5 &
[bg] PID=12350 lancé en arrière-plan
mini-shell> date
mer. 15 oct. 2025 14:30:12 CEST
mini-shell> exit
Au revoir !
Vous pouvez ajouter petit à petit des éléments à votre shell comme pouvoir lancer des commandes en background quand la ligne se termine par &, créer les fonctions comme cd ou history (voir la commande help dans un terminal bash si vous voulez de l’inspiration).