Vous êtes sur la page 1sur 30

4 Exemple dun tube Unix

Partie sur les tubes Unix


 Exemple dapplication du modle
producteur/consommateur
 Tubes volatiles (non nomms)






Principes et smantique
API de cration, contrle
Exemple complet
Flux doctets vs. Messages
Exemple de redirection : mise en uvre du | shell

 Abstraction de haut niveau (s3) pour sous-traiter


 Tubes non volatiles, cad persistants, et nomms

4.1 Tube volatile

Tube Unix : synchronisation &


communication via un flot doctets
 2 Rles, par oprations classiques E/S sur fichier:
 Producteur: crire des donnes dans le tube
 Consommateur: lire des donnes depuis le tube

 Synchronisations :
proc. n4

proc. n1

tube unidirectionnel

proc. n2

proc. n5

extrmit
de lecture

proc. n3

lecteurs

extrmit
dcriture

proc. n7

crivainsrelecteurs

proc. n6

crivains

 Tube plein: bloquer


criture
 Tube vide: bloquer lecture
 Lectures en FIFO
 Operations Lecture &
Ecriture atomiques
 Arrt lecture ds que tube
vide et plus dcrivain
 Arrt immdiat criture si
plus de lecteurs
 Destruction auto. du tube

4.1 Tube volatile

API Unix Tube: principe gnral

 Cre un tube dans le noyau, de capacit PIPE_BUF octets et place dans


le tab. de 2 entiers les fd de chaque extrmit du tube
 Utilisable uniquement par le processus et sa descendance cre aprs
le tube (hritage) car le tube est anonyme (vs. Tube nomm)
 Read et write servent pour lire ou crire dans le tube
 Les autres primitives qui manipulent des fd sont utilisables (sauf lseek,
car FIFO !)
 Le tube est volatile : disparat lorsque plus aucun processus ne peut
lutiliser parce quaucun fd ne le rfrence (au plus tard la
terminaison des processus qui ont le droit de lutiliser via leurs fds =>
fermeture automatique des fds lors de exit)

4.1 Tube volatile

Tube: Gestion des file descriptors

1) pipe ( fd )

processus pre

processus fils

2) fork ( )
fd[0]

hrite de fd[0] et fd[1]


fd[0]

fd[1]

fd[1]

lecteur
et/ou
crivain

lecteur
et/ou
crivain

potentiel

potentiel

lecture

fd[0] : descripteur de fichier


Extrmit du tube en Lecture
fd[1] : descripteur de fichier

tube

extrmit de

Retour pipe : Paire

extrmit

dcriture

Situation aprs cration du tube et dun processus fils

Extrmit du tube en Ecriture

4.1 Tube volatile

Tube: Gestion des file descriptors (2)


processus pre

processus fils

close ( fd[0] )

close ( fd[1] )

fd[0]

fd[0]

fd[1]

fd[1]

crivain

lecteur

Fermeture du tube

Fermeture de la dernire extrmit


dcriture => tentative de lecture

extrmit de lecture

dtectera fin de fichier

tube
extrmit

dcriture

Fermeture de la dernire extrmit


de lecture => envoi dun SIGPIPE

Situation 1 aprs deux fermetures


crivain

lors de toute tentative dlecteur


criture

pre :
close ( fd[0] )

fils :
fd[1]

extrmit dcriture

tube

fd[0]

extrmit de lecture

close ( fd[1] )

4.1 Tube volatile

Tube: Gestion des file descriptors (3)

processus pre

processus fils

close ( fd[1] )

close ( fd[0] )

fd[0]

fd[0]

fd[1]

fd[1]
crivain

lecteur

tube
extrmit de lecture

extrmit dcriture

Situation 2 aprs deux fermetures


lecteur

crivain

pre :

fils :
fd[0]

close ( fd[1] )
extrmit de lecture

tube

fd[1]

extrmit dcriture

close ( fd[0] )

4.1 Tube volatile

Tube: Gestion des file descriptors (4)


processus pre

1) pipe ( fd )

processus fils 1

2) fork ( )

hrite de fd[0] et fd[1]

3) fork ( )
fd[0]

fd[0]

fd[1]

fd[1]

lecteur
et/ou
crivain

lecteur
et/ou
crivain

potentiel

potentiel
tube
extrmit dcriture

extrmit de lecture

lecteur
et/ou
crivain

processus fils 2

potentiel

hrite de fd[0] et fd[1]


fd[0]

fd[1]

Situation aprs cration du tube et de 2 processus fils

4.1 Tube volatile

Tube: Gestion des file descriptors (5)


processus pre

processus fils 1

close ( fd[0] )
fd[0]

close ( fd[1] )
fd[0]

fd[1]
crivain

fd[1]
lecteur

extrmit de lecture

tube

extrmit dcriture

processus fils 2
close ( fd[1] )
fd[0]
lecteur

fd[1]

lecteurs

Situation aprs fermetures de certaines extrmits du tube

fils 1 :
fd[0]

crivain
pre :
close ( fd[0] )

fd[1]

extrmit dcriture

tube

close ( fd[1] )

extrmits de lecture

fils 2 :
fd[0]

close ( fd[1] )

4.1 Tube volatile

Tube: lecture et criture FIFO


 Par dfaut, lecture et criture sont bloquantes
 Ecriture (rle Producteur)
 Possible ssi encore des lecteurs
 atomique si nb. Car < PIPE_BUF, interruptible sinon
 & bloquante, attendant que des consos. aient eu lieu pour
parvenir rentrer les nb. car dans le tube

 Lecture (rle Consommateur)


 dau plus le nombre de car. souhaits
 Il faut donc tester le nombre de car. effectivement lus

 0 car. si la fin de fichier est dtecte


 sinon, bloque le processus appelant (attendant que des
productions aient eu lieu)
 Do limportance de dtecter FdF, sinon blocage est dfinitif
 Donc, penser fermer les extrmits en criture si plus besoin

4.1 Tube volatile

Exemple, pre crivain / fils lecteur

4.1 Tube volatile

Exemple, pre crivain / fils lecteur (2)


 Le pre
construit des
donnes, puis
les envoie au
fils au travers
du tube, avant
de fermer son
extrmit en
criture

4.1 Tube volatile

Exemple, pre crivain / fils lecteur (3)


 Le fils ne sait
pas combien
doctets il doit
lire : il les
traite au fur et
mesure de
ses lectures

4.1 Tube volatile

Informations sur un tube : fstat(2)


 fstat appliqu lune quelconque des extrmits du
tube donne quelques informations sur ses proprits
Type du fichier: FIFO
Permissions: rw pour le propritaire
Propritaire: celui du processus crateur
Groupe: celui du processus crateur
i-node: indfini
Dates st_ctime, st_atime, st_mtime : tous la date de
cration du tube
 Taille st_size: nb doctets prsents dans le tube







4.1 Tube volatile

Communication par messages avec


un tube
 Doit respecter les limites des messages, eux-mmes
de taille quelconque
 Un tube ne le permet pas par dfaut
 Car cest un flot doctets, non structur
 Nombre de write peut tre diffrent de nb de read

 Adjoindre au message un prambule indiquant la


longueur du contenu du message
 Lire en 2 tapes:
 Prambule (taille fixe au pralable) qui indique longueur du
contenu
 Contenu
 Attention, changes de messages ne sont pas forcment
atomiques car les messages ont une longueur quelconque
 2 reads de 2 lecteurs entrelacs besoin gestion dune section
Critique!

4.1 Tube volatile

Exemple, fils crivain / pre lecteur (1)

4.1 Tube volatile

Exemple, fils crivain / pre lecteur (2)


 Le pre lit
jusqu fin de
fichier une
taille de
message suivi
du message
(contenu)

2 reads:
lecture du message complet
pas forcment atomique

4.1 Tube volatile

Exemple, fils crivain / pre lecteur (3)


 Le fils
construit
plusieurs
messages dans
un tampon,
quil envoie au
fur et
mesure au
pre
Un seul write & < PIPE_BUF:
criture atomique

4.1 Tube volatile

Exemple : redirection E/S vers tube


 Un processus produit des donnes,
consommes puis traites par son fils
 head -20 fichier | grep expression
 grep expression | more => *pageur*, cad page/page
processus fils

processus pre

producteur

tube unidirectionnel

cre un tube et

pageur
lit sur STDIN et

un fils
crit sur STDOUT

crit sur fd[1]


fd[1]

redirection STDIN
sur fd[0]

Le processus fils fait une redirection


avant de charger (exec) le programme pageur

4.1 Tube volatile

Code du processus producteur


 Produit des donnes sur STDOUT
 Modifier au minimum son code pour quil envoie ces
donnes vers le tube

4.1 Tube volatile

Programme principal (ici, le pre)


 Pourrait tre
+/- ce quun
shell excute
 si ligne de cmd
contient |

Pre a ouvert le fichier (fpin),


& donn en hritage au pageur .
Mais il ne lutilisera pas, car il
lit les lignes depuis le tube.

4.1 Tube volatile

Producteur modifi pour tube

 Considre que
STDOUT est
redirige vers
extrmit
criture du
tube

4.1 Tube volatile

Consommateur: pageur
 Lit sur STDIN, redirige sur extrmit lecture tube

4.2 Abstraction pour |

Abstraction pour sous-traitance


 Abstraction pour pre | /bin/sh e cmd ou +/linverse: /bin/sh e cmd | pre
 Processus pre cre un fils /bin/sh afin quil
excute une certaine commande, cre un tube,
abstrait par un FILE dans le code,
 et se sert du tube pour lui passer des donnes sur
lesquelles le fils va travailler :
popen, en mode w cot pre
 ou se sert du pipe pour attendre des donnes fabriques
par son fils
popen, en mode r cot pre

 Lorsque le pre le dcide, il ferme le pipe et


attend la terminaison de son fils (fin cmd puis sh) :
 pclose

4.2 Abstraction pour |

popen en w , write
pre

fils

f=popen( "cmde...", "w")

Commande shell

tube
lit des donnes
fprintf(f,"fmt", donnes)

redirection STDIN

sur STDIN

sur fd [ 0 ]

 pclose du pre dclenche Fin de Fichier dans le


tube
 Le fils va pouvoir se terminer
 Le pre va pouvoir attendre code retour de son fils (wait)

4.2 Abstraction pour |

popen en r , read
pre

tube

f=popen( "cmde...", "r")

fils
Commande shell

crit des donnes


redirection STDOUT
fscanf (f,"fmt", donnes)

sur STDOUT

sur fd [ 1 ]

 pclose du pre
 Le pre va tre bloqu jusqu la fin de son fils
(wait)

4.2 Abstraction pour |

API de popen et pclose (man 3)

4.2 Abstraction pour |

Exemple avec cmd = un pageur

Pre crit les


lignes du fichier
dans le tube

4.3 Tube persistant

Tube persistant, nomm


 Appel aussi FIFO, entit explicite et ayant un nom au
sein du systme de fichiers
 Par rapport un tube volatile :
 accessible par des processus






qui ne sont pas de la mme descendance


nont pas le mme utilisateur crateur, mais les permissions
peut exister alors mme que le processus crateur du FIFO a fini
et que plus aucun processus ne lutilise
ls l: p rw- r-- r-- 1 nom_util nom_groupe size date nomDuFifo

 Un FIFO est un canal de communication, par flot


doctets, et persistant
 utilisable pour raliser 1 architecture client(s)/serveur(s) sans
fichier temporaire explicite
 sur une mme machine: les processus clients et serveur
doivent sexcuter sur le mme CPU, et le tube doit tre gr
par le noyau qui gre ces processus (pas de NFS)

4.3 Tube persistant

Mode standard dutilisation dun FIFO


 Cration par mkfifo (1), mkfifo(3)
 Ouverture dans un mode (read, ou write)
ncessite quun autre processus louvre dans
le mode complmentaire (write ou read):
 Bloquant tant que la condition nest pas vrifie
 Ralise un rendez-vous entre processus

 Utilisation habituelle par read et write, fstat


 Bloquant si rien lire ou tube plein, mode
prod/cons

 Destruction par rm(1) ou unlink(2) et plus


aucun lecteur ou crivain utilisant le tube

4.3 Tube persistant

Crer & ouvrir un tube FIFO


 mkfifo(2)

Seuls modes
autoriss en
ouverture pour un
FIFO

 open (2) : rappel


O_RDONLY: ouverture en lecture seule.
O_WRONLY: ouverture en criture seule
(cration ou ajout)