A.
TP N°4 : La communication inter-
processus sous Linux
Objectifs
A l'issue du TP l'étudiant devra être capable de :
Comprendre et implanter une communication entre les processus en utilisant les tubes anonymes en
langage C
Comprendre et implanter une communication entre les processus en utilisant les tubes nommés en
langage C
Exercice 1
Écrire un programme C qui crée un processus fils.
• Le processus père lit des caractères sur l'entrée standard et l’envoie à son fils.
• Le processus fils compte les lettres et les chiffres et affiche les résultats.
• Le processus père attend la terminaison du fils pour s'arrêter.
Exercice 2
Écrire un programme C qui permet de :
• Créer deux fils.
• Fils1 envoie à son frère « Bonjour ».
• Fils2 reçoit le message de son frère et l’affiche sur l’écran.
• Fils2 envoie à son frère «Quelle Belle journée !».
• Fils1 reçoit le message de son frère et l’affiche sur l’écran.
Exercice 3
Écrire un programme C qui permet de créer 2 programmes p1.c et p2.c :
• le programme p1 permet de saisir une chaîne de caractères et de l’envoyer à p2 via un
tube nommé.
• Le programme p2 permet de lire cette chaîne qu’il a reçue à travers le tube et l’affiche
sur l’écran.
1/5
Rappels
A) Les tubes anonymes
Les tubes (pipes en anglais) sont des canaux de communication unidirectionnels.
Un tube se comporte comme une file FIFO (First In First Out ) : les premières données
entrées dans le tube seront les premières à être lues. Toute lecture est destructive.
Les tubes sans noms sont temporaires, il n'existe que le temps d'exécution de processus qui
les a crées.
Les tubes sans noms sont utilisés pour la communication entre des processus ayant un lien
de parenté (un processus père et ses processus fils), avec un d'entre eux qui écrit sur le tube,
appelé processus écrivain, et l'autre qui lit à partir du tube, appelé processus lecteur.
Les tubes sont manipulés à l’aide de descripteurs de fichiers. Tout processus ayant accès à
ces descripteurs peut lire ou écrire dans un tube.
Il y a simplement quatre primitives fondamentales pour les tubes.
1. int pipe (int descripteur[2]) crée un tube et retourne 0 en cas de succès, -1 en cas
d’échec. Après appel:
o descripteur [0] est le descripteur du tube créé en lecture
o descripteur [1] est le descripteur du tube créé en écriture.
2. int write (int descripteur, char buffer, int longueur) écrit dans le tube ayant un
2/5
descripteur en écriture les longueur octets commençant en mémoire à l’adresse buffer.
La primitive renvoie le nombre d’octets écrits ou -1 en cas d’échec.
Exemple: write(p[1],&v,sizeof(float)) permet d'écrire la variable v de type float dans le
descripteur d’un tube en écriture (p[1])
3. int read (int descripteur, char buffer, int longueur) lit longueur octets (au maximum)
dans le tube ayant un descripteur en lecture et place ces octets en mémoire à partir de
l’adresse buffer.
La primitive renvoie le nombre d’octets lus, ou 0 si le tube est vide et qu’il n’y a plus
d’écrivains sur le tube ou enfin -1 en cas d’erreur. S’il reste un écrivain mais que le tube
est vide, le processus se bloque en attente d’information.
Exemple: read (p[0], &v, sizeof(float)) permet de lire un nombre flottant à partir du
descripteur d’un tube en lecture est p[0] et le placer dans la variable v.
4. int close (int descripteur) ferme le tube en lecture ou en écriture (en fonction du
descripteur passé en argument), pour le processus ayant appelé close seulement.
Il renvoie 0 en cas de succès ou -1 en cas d’échec.
La séquence d'événements pour une telle communication est comme suit :
1. Le processus père crée un tube de communication sans nom en utilisant l'appel système
pipe()
2. Le processus père crée un ou plusieurs fils en utilisant l'appel système fork()
3. Le processus écrivain ferme l'accès en lecture du tube (close (T[0]) )
4. De même, le processus lecteur ferme l'accès en écriture du tube (close (T[1]) )
5. Les processus communiquent en utilisant les appels système write() et read()
6. Chaque processus ferme son accès au tube lorsqu'il veut mettre fin à la communication via
le tube
B) Les tubes nommés
Ce sont des tubes qui ont l'avantage de connecter des processus quelconques,
sans lien de parenté particulier.
La commande ls -l par exemple, les affichent avec la lettre p, comme pipe,
en position type de fichier.
prw-r--r-- 1 tounsi 0 Jun 26 17:11 canal
3/5
Un tube nommé est donc un fichier spécial permettant à des processus
quelconques d'échanger des données en mode fifo comme dans un tube normal.
1. Création
La création d'un fifo se fait à l'aide de la primitive mkfifo()
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(char *nom, mode_t pmode);
Le paramètre nom indique le nom du tube fifo à créer et le paramètre pmode ses
droits d'accès (généralement 0644 cf. mode fichiers ordinaires). mkfifo() rend 0
en cas de succès (tube créé) ou -1 en cas d'échec (fichier de même nom existe ou
autre anomalie etc.).
Exemple:
if (mkfifo("canal", 0644) < 0)
fprintf(stderr,"erreur mkfifo\n");
2. Ouverture
• Ouvertures possibles par les processus connaissant le nom du tube
#include <sys/types.h>
#include <sys/stat.h>
int open(const char *filename, int flags);
// Exemples:
open(”fifo”, O_RDONLY); // ouverture en lecture seule
open(”fifo”, O_WRONLY); // ouverture en écriture seule
3. Lecture & Ecriture
Peuvent être lu ou écris comme des fichiers ordinaires
– en utilisant les primitives systèmes (bas niveau) : read, write
– en utilisant les fonctions de la librairie (haut niveau)
4/5
4. Fermeture
Primitive close()
int close(int fd);
Fermer tous les descripteurs non utilisés évite les situations de blocage .
Fermeture d’un tube libère le descripteur pour le descripteur d’écriture, agit comme une fin de
fichier.
5/5