Cours : Les tubes anonymes
Ce cours s'intéresse à un premier outil de communication entre
processus
placés sur une même machine : les tubes anonymes.
Un tube (pipe en anglais) est un fichier particulier. Il existe deux types de tube:
. les tubes anonymes . les tubes nommés
Le fichier tube est un outil de communication unidirectionnel qui est géré par le noyau comme une file de données FIFO. Les
lectures sont destructives car tout caractère lu est extrait de la file d'attente. Deux nombres im
port
ants caractérisent le tube:
- le nombre de lecteurs : si ce nombre est nul, les lectures ne sont pas autorisées dans tube.
- le nombre d'écrivains : si ce nombre est nul, . il est équivalent à une fin de fichier.
1 Définition et propriétés d'un tube anonyme.
Un tube anonyme encore appeler tube ordinaire est associé à un nud du système de gestion de fichiers, mais il représente
un fichier qui n'a pas de nom. Ce fichier est supprimé dès qu'il n'y a plus de processus pour l'utiliser. Un
tube anonyme
n'ayant pas de nom, il ne peut être connu que par la possession des descripteurs qui lui donnent accès. La connaissance de
ces descripteurs par un processus s'effectue de deux moyens:
- Le processus connaît les descripteurs associés au tube car il a créé le tube.
- Le processus connaît les descripteurs associés au tube car il a hérité de ces descripteurs.
On voit donc que seuls les processus de la descendance du créateur du tube dont les ancêtres connaissent eux-mêmes les descripteurs
sont habilités à utiliser le tube. Un tube anonyme permet donc la communication entre des processus de même filiation père-fils
ou frères s'exécutant sur une même machine. Il faut noter également que les tubes ne préservent pas la limite des messages
postés dans le tube.
Définition : Tube anonyme
Un tube anonyme est un outil de communication unidirectionnel permettant de faire communiquer entre eux des processus de même
filiation, ayant connaissance des descripteurs permettant l'accès au tube.
2 Les primitives associées au tube anonyme
2.1 La création d'un tube
En créant le tube le processus1 se dote de 2 descripteurs:
- . un descripteur en Lecture sur le tube
- . un descripteur en Ecriture sur le tube
La
primitive pipe
(p) où le paramètre p est un tableau de deux entiers correspondant aux deux descripteurs d'accès au tube permet la création
du tube anonyme p, avec p[0] comme descripteurs en lecture et p[1] comme descripteur en écriture.
Définition : Primitive pipe
int pipe (int p[2]) : création du tube p.
2.2 La fermeture du tube
La fermeture du tube et sa destruction ont lieu lorsqu'il n'existe plus aucun processus utilisant le tube, c'est-à-dire qu'il
n'existe plus aucun descripteurs ouverts pour ce tube, que ce soit en lecture ou en écriture. La
primitive close
(idf) permet de fermer le descripteur idf .
Définition : Primitive close
int close (int idf) : fermeture du descripteur idf.
2.3 Lecture dans le tube p
La primitive nb_lu = read (p[0], buf, nb) permet la lecture dans le tube p d'au plus nb caractères. Elle retourne les caractères
dans le tampon buf et nb_lu contient le nombre de caractères effectivement lus. L'opération de lecture répond à la sémantique
suivante :
- si le tube n'est pas vide, et contient N caractères, le nombre de caractères effectivement lus, nb_lu est égal à min (N, nb).
- Si le tube est vide et que le nombre d'écrivains sur le tube est nul, la fin de fichier est atteinte. Nb_lu = 0.
- Si le tube est vide et que le nombre d'écrivains sur le tube n'est pas nul, le
processus
est bloqué jusqu'à ce le tube ne soit plus vite (un écrivain a écrit). En effet, par défaut, l'opération de lecture sur un
tube vide est bloquante. Il est possible de rendre la lecture non bloquante, mais nous n'abordons pas cette option dans le
cours.
Définition : Primitive read (tube)
nb_lu = read (p[0], buf, nb) : lecture dans le tube p d'au plus nb caractères. Les caractères lus sont retournés dans le tampon
buf. nb_lu contient le nombre de caractères effectivement lus. Par défaut, la lecture sur un tube vide est bloquante.
2.4 Ecriture dans le tube p
La primitive nb_écrit = write (p[1], buf, nb) permet l'écriture dans le tube p des nb caractères placés dans le tampon buf
et nb_lu contient le nombre de caractères effectivement écrits. L'opération d'écriture répond à la sémantique suivante :
- Si le nombre de lecteurs dans le tube est nul, une erreur est levée par le système (signal SIGPIPE levé) et le processus écrivain
est terminé. En effet, le système considère que si il n'y a plus de lecteurs dans le tube, il est inutile d'y écrire puisque
les caractères écrits ne pourront jamais être lus.
- Si le nombre de lecteurs dans le tube n'est pas nul, le retour de la primitive n'a lieu que lorsque les nb caractères ont
effectivement été écrits. En effet par défaut, l'écriture sur le tube est bloquante. Il est possible de rendre l'écriture
non bloquante, mais nous n'abordons pas cette option dans le cours.
Définition : Primitive write (tube)
nb_écrit = write (p[1], buf, nb) : écriture dans le tube p des nb caractères placés dans le tampon buf. nb_lu contient le
nombre de caractères effectivement écrits.
3 Un exemple de programmation avec les tubes anonymes.
#include <stdio.h>
int pip[2]; /* descripteur de pipe */
char buf [6];
{ main()
pipe(pip); /* creation pipe */
switch (fork())
{case -1: perror("fork"); exit(1);
case 0: fils();
default: pere();}
pere(){close pip[0]; write (pip[1],"hello",5); exit(0);} /* écriture pipe */
fils() {close pip[1]; read (pip[0],buf,5); exit(0);} /* lecture pipe */
}
On voit dans l'exemple ci-dessus :
- La création du tube a lieu avant la création du processus fils, afin que celui-ci puisse hériter des descripteurs du tube
et donc l'utiliser pour communiquer avec son père.
- Chacun des processus, le père et le fils, ferme le descripteur qui lui est inutile : ainsi le père ferme pip[0], le descripteur
en lecture puisqu'il est écrivain sur le tube. Inversement, le fils ferme pip[1], le descripteur en écriture puisqu'il est
lecture sur le tube.
Outils de communication centralisés entre processus
Les tubes anomymes
|