TD Série 3 Tubes Correction
TD Série 3 Tubes Correction
TD Série 3 Tubes Correction
Département Informatique
Licence S6
Notions Abordées :
• Les tubes : pipe(), read(), write(), close(), fork(), dup()/dup2().
Exercice 1
Ecrire le programme C sous Unix qui permet à un processus père de créer un processus Fils. Le fils
récupère une chaine de caractère l’écrit dans un tube. Le père lit du tube caractère par caractère et
l’affiche en majuscule.
Correction :
Rappel sur les tubes anonymes :
• Ils sont implémentés comme des fichiers mais n’ayant aucun nom physique (il n’existe que pendant
l’exécution du programme).
• Un tube est une forme de redirection utilisé pour envoyer la sortie d’un programme à un autre
programme.
Correction Exercice 1 :
Un programme C qui réalise ce qui suit:
• Le fils récupère une chaîne de caractère (soit à partir d’un argument du main, soit entrée par un
utilisateur), et l’écrit dans le tube
• Le père lit du tube caractère par caractère et l’affiche en majuscule.
1
La sortie standard Stdout
l’entrée standar Stdin (l’écran)
(le clavier)
Processus 2
Processus 1
Processus Père
Processus Fils
Par définition
fd[0] est le descripteur (prédéfini) par lequel on peut lire dans le tube.
fd[1] est le descripteur par lequel on peut écrire dans le tube.
NB : Si le tube est créé par un processus avant la création de ses fils, alors ses fils héritent alors du
descripteur du père. Par conséquent , il faut utiliser pipe avant d’utiliser fork.
Après sa création, un tube est directement utilisable. Par contre, sa fermeture se fait en appelant
la fonction close().
Pour être certain de qui va écrire et qui va lire dans la pipe, il faut fermer les deux extrémités non-
utilisées. En effet, en écrivant dans la pipe sans fermer l’extrémité inutilisée, on ne sait pas lequel des
deux processus va recevoir l’information. Cela, peut donner des résultats inattendus.
}
else
{ //Le Père
close(fd[1]); // On ferme le descripteur d'écriture pour le père
2
Dans le cas de cet exercice, en fermant le descripteur de lecture fd[0] pour le processus fils et le
descripteur d’écriture fd[1] pour le père, on peut être certain que le fils écrit dans la pipe (fd[1]), et que
le père va recevoir l’information en lecture (fd[0]).
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<wait.h>
#include<ctype.h>
#define MAX 25
int main(){
char buffer[MAX];
char c;
int nbc;
int pid, fd[2];
if(pipe(fd) < 0)
exit(1);
pid = fork();
if (pid == -1){
perror("fork");
exit(1);
}
if(pid == 0){
close(fd[0]); // On ferme le descripteur de lecture pour le fils
printf(" Entrez une chaine de caractère : ");
scanf("%s", buffer);
write(fd[1], buffer, strlen(buffer) * sizeof(char));
close(fd[1]); // Après avoir terminé l'écriture dans le tube, on ferme le descripteur d'écriture
}
else
{
//Le père
//wait(NULL);
close(fd[1]); // On ferme le descripteur d'écriture pour le père
printf("\n");
close(fd[0]); // Après avoir terminé la lecture à partir du tube, on ferme le descripteur de lecture
}
return 0;
}
Ecrire le programme C sous Unix qui permet à un processus père de créer un processus Fils. Le père
et le Fils doivent s’exécuter en parallèle et permettent l’affichage suivant :
Fils: 2 4 6 8 10
Père: 13 16 19 22 25
3
Indication :
Le Fils doit informer le père de la dernière valeur affichée.
On utilise un tube pour la communication Père/Fils.
Correction de l’Exercice 2 :
Processus
Processus Père
Fils
Écrit la dernière
Affiche :
valeur (10) dans
13 16 19 22 25
le tube
Envoie la dernière
Lire à partir du tube
valeur dans le tube
(Le descripteur fd[0])
(le descripteur fd[1]) Le tube (pipe) est un
buffer ou un bloc de
données avec deux
descripteurs de fichiers
fd[2].
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<wait.h>
#include<ctype.h>
#define MAX 25
int main(){
int p[2];
int pid, i = 1;
int n1;
if(pipe(p) == -1)
{
perror("pipe");
exit(-1);
}
pid = fork();
if(pid == 0){
do{
n1 = i * 2;
printf(" %d ", n1);
i ++;
}while (n1 % 5 !=0);
printf("\n");
close(p[0]);
write(p[1], &n1, 1 * sizeof(int));
close(p[1]);
} else{
wait(NULL);
close(p[1]);
do{
n1 = n1 + 3;
printf(" %d ", n1);
}while(n1 % 5 !=0);
printf("\n");
close(p[0]);
}
}
4
Exercice 3 : Redirection des Entrée/Sortie
Ecrire le programme C sous Unix qui permet d’afficher le nombre de processus en cours d’exécution.
Correction de l’Exercice 3 :
Redirection vers
l’entrée de la
commande wc –l .
ps -A wc -l
Sortie de la
commande ps -A
Cela revient à exécuter la commande sous Unix ps -A | wc -l Deux processus Fils et père : le père
exécute la commande : ps -A et redirige le résultat dans un tube. Le fils exécute la commande wc -l avec
comme entrée le contenu du tube(redirection de l’entrée standard).
On utilise également l’appel execlp() qui permet de remplacer le processus en cours par l’exécution
d’une commande.
Le code :
5
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<wait.h>
#include<ctype.h>
if ( pid == -1)
{
perror("fork");
exit(1);
}
if (pid == 0)
{
/* le fils */
close(fd[1]); /* ferme le descripteur d'écriture */
dup2(fd[0], 0); /* connecte le descripteur de lecture avec le stdin */
close(fd[0]); /* ferme le descripteur de lecture*/