Projet DVD-MIAGE 2010 : TP n°5 - Communication et synchronisation (les tubes)
Travail à effectuer
Analysons le code suivant et étudions son comportement en supprimant certaines lignes.
Code initial
#include <stdio.h>#include <unistd.h>#include <ctype.h>int main(void){char c;int fd[2];pipe(fd);if (!fork()){while (read(0, &c, 1) > 0)write(fd[1], &c, 1);fprintf(stderr, "écrivain fini\n");}else{close(fd[1]);while (read(fd[0], &c, 1) > 0){c = toupper(c);sleep(1);write(1, &c, 1);}fprintf(stderr, "lecteur fini\n");}return 0;}Questions et réponses
- Question : Que se passe-t-il si on supprime la ligne
close(fd[1])dans le processus fils (lecteur) ? Pourquoi ?Réponse : Sans leclose(fd[1]), le processus père (écrivain) ne se termine pas car le tube reste ouvert. Le processus fils bloque indéfiniment surread(0, &c, 1)en attendant des données, tandis que le processus père continue d'écrire sans pouvoir se terminer proprement. Cela crée une situation de deadlock où les deux processus restent bloqués. - Question : Comment modifier le code pour que le processus père soit l'écrivain ?Réponse :
#include <stdio.h>#include <unistd.h>#include <ctype.h>int main(void){char c;int fd[2];pipe(fd);if (!fork()){close(fd[1]);while (read(fd[0], &c, 1) > 0){c = toupper(c);sleep(1);write(1, &c, 1);}fprintf(stderr, "lecteur fini\n");}else{while (read(0, &c, 1) > 0)write(fd[1], &c, 1);fprintf(stderr, "écrivain fini\n");}return 0;} - Question : Comment remplacer le code du lecteur par un appel à
execl?Réponse :#include <stdio.h>#include <unistd.h>#include <ctype.h>#include <stdlib.h>int main(void){char c;int fd[2];pipe(fd);if (!fork()){close(fd[1]);dup2(fd[0], STDIN_FILENO);execl("./lecteur", "./lecteur", NULL);perror("execl");exit(EXIT_FAILURE);}else{while (read(0, &c, 1) > 0)write(fd[1], &c, 1);fprintf(stderr, "écrivain fini\n");}return 0;}Contenu du fichier
lecteur.c:#include <stdio.h>#include <unistd.h>#include <ctype.h>>int main(void){char c;while (read(0, &c, 1) > 0){c = toupper(c);sleep(1);write(1, &c, 1);}fprintf(stderr, "lecteur fini\n");return 0;}
Foire aux questions (FAQ)
1. Qu'est-ce qu'un tube (pipe) en programmation système ?
Un tube, ou pipe en anglais, est un mécanisme de communication inter-processus (IPC) qui permet à deux processus liés (père et fils) d'échanger des données via un flux unidirectionnel. Il est principalement utilisé pour connecter la sortie standard d'un processus à l'entrée standard d'un autre.
2. Pourquoi le processus père ne se termine-t-il pas si le tube n'est pas fermé ?
Le processus père attend que le processus fils se termine pour récupérer son code de sortie. Si le processus fils ne ferme pas son extrémité d'écriture du tube, le processus père ne peut pas détecter la fin des données et reste bloqué indéfiniment sur la fonction write, ce qui crée un deadlock.
3. Que signifie dup2 dans le contexte des tubes ?
La fonction dup2 est utilisée pour rediriger un descripteur de fichier. Dans ce cas, elle redirige l'entrée standard (STDIN_FILENO) vers le tube de lecture (fd[0]), permettant ainsi au programme exécuté par execl de lire directement les données provenant du tube.