Communication synchrone Unidirectionnel Limitations: Taille, sérialisation, ... Mécanismes: voir cousrysstèmes de fichiers Intra-machine Volatiles ou persistants (FIFO ou tube nommé)
ÎImplémentation du shell>:,<,|
Bidirectionnel : Syst. V R.4 implantation par les sockets sur linux
N°257
Version Janvier 2008 N°258 pipe: tube de communication Descripteurs en lecture et écriture Paramètre résultat utilisable directement avec 9write 9read 9
Création d’un tube Disparait si plus aucun processus ne peut l’utiliser Utilisable par la descendance (exclusivement) 9fork 9execve
1
Version Janvier 2008
pipe: avec un processus (1)
mai { }
Sens du flux
fd[1]
fd[0]
#include <unistd.h> int main () { int fd[2]; int err; char *s1, *s2; s1 = "chaine1"; s2 = (char *)malloc(10); err =pipe(fd); write(fd[1], s1, 8 read(fd[0], s2, 8) ... }
N°259
Version Janvier 2008 N°260 pipe: avec un processus (1) 0 1O_RDONLY 2pipe[0]État :1 3Nombre : 4mpyipeenano5N° inode :2 t : . copies : NÉtoambre:OWRONLYObNfets1_Of0tes 1IedonInfos EspaceutilisateurTablefichiersTableinodes
Version Janvier 2008
0
pipe : entre deux processus (1)
Le fils « hérite » des descripteurs du père les deux processus : lecteur et/ou écrivain Echange : un seul sens mais n’importe lequel
9
blocs
N°261
2
Version Janvier 2008 pipe : entre deux processus (2)
Fermeture d’une des extrémités dans chaque processus et un seul « lecteur »Un seul « écrivain » Choix arbitraire d’un sens « père » vers « fils »
Version Janvier 2008
pipe : entre deux processus (3)
#include <unistd.h> int main () { int fd[2], pid; char *s1, *s2; int err; ... s1 = "chaine1"; iefr(r(=pipdip=ef(ofrdk(0)))<ru;;r)eer? if(pid==0){/*Traitements2 = (char *)malloc(10); close(fd[1]); read(fd[0], s2, 8);} else{/*Traitementpère*/close(fd[0]); write(fd[1], s1, 8);} ... }
Version Janvier 2008 pipe : entre deux processus (4) Sens du flux 5301 5302
ffdd[[01]]
fd[1]
fd[0]
N°262
N°263
N°264
3
Version Janvier 2008 N°265 pipe : entre deux processus (5) 0 ORDONLY 1_ 2pipe[État : 30]Nombre2 : 4empeiynonpa 5N° inode :2 État:NOb.fcopies : Nombre :OWRONLY0est _Of1est 0fosdeInIon 12 2 3 4 5EspaceutilisateurTablefichiersTableinodes Version Janvier 2008 N°266 pipe : entre trois processus (1)
Version Janvier 2008 pipe : entre trois processus (2)
Fermeture d’une des extrémités dans chaque processus : le pèreUn seul « écrivain » et deux « lecteurs » : les fils Toute combinaison est possible
N°267
4
Version Janvier 2008 N°268 pipe: compléments (1) Informations complémentaires Utilisation de blocs directs Structure FIFO (premier écrit, premier lu) ÆGestion d'une file circulaire Position de déplacement: dans l'inode ÆFichier ordinaire: dans la table des fichiers Lecture (non) bloquanten:o_delay Cas limites Tube vide ou sans « écrivains » : lect⇒ureEOF readretourne 0 -sinon si rien à lire: blocage ⇒» si processus pas « écrivain »fermer « fd[1] Tube sans « lecteurs » : écritu⇒resignal SIGPIPE Version Janvier 2008 N°269 pipe: compléments (2) Echange par flots ou messages (programmation) En général si « message » : lecture/écriture atomique Ecriture : interruptible⇒Ecriture non atomique Atomique : nb octets à écrir<ecapacité tube Voirfpathconf Attente possible si pas assez de place Lecture : les octets lus sont retirés du tube aucune garantie d’atomicité ou complétude Tester le nb octets lu et itérer
Version Janvier 2008 N°270 pipe/dup: exemple du pipe shell (1) bash Stdin0Stdout1 Père Stderr2 fork() exec() exec() Stdin0 1SuodtttS1 Fil Stde Stderr2 ls -l wc -l
5
Version Janvier 2008 pipe/dup: exemple du pipe shell (2) #include <unistd.h> int main () { int pid, nfd; int tab[2]; .../*analysecommande*/if ( (pid =forktu1*)//*d(bé=={0)))( .../*Traitementredirection*/...if(/*miseentube*/){/*(début2)*/pipe(tab); if ( (pid =fork()) == 0) { /*partiegauchepipe:stdout>tube*/-closestdout); nfd =dup(tab[1]); /* nfd = stdout */ close(tab[1]); close(tab[0]); execlpgauche, ...); }
Version Janvier 2008 pipe/dup: exemple du pipe shell (3)
#include <unistd.h> int main () { /*débutsurT.précédent*/ if/*miseenuteb/*itsu2)e*/){*/(/*partiedroitepipe:stdin-->tube*/closestdin); nfd =dup/*nistdnfd=/*0]);at[b( close(tab[0]); close(tab[1]); }/*fin2*//*suite1*/execvedroit, ...); } /* fin 1 */ if (/* &*/)wait(&status); }
N°271
N°272
Version Janvier 2008 N°273 pipe/dup: exemple du pipe shell (4)
0 1 2 3 4 5
0 1 2 3 4
5Espaceutilisateur
ORDONLY _ État :3 Nombre : pipeanonyme N° inode :2 : : Nb. copies État Nombre : Of0est O_WRONLYOfest1 3sfonoIInde
Tablefichiers
Tableinodes
6
Version Janvier 2008 N°274 Tube nommé: Principaux aspects Points commun avec « pipe » Unidirectionnel Toujours intra-machine Toujours FIFO ceavecdifféren’lcaècsp«pi»e: Un fichier avec un nom Partage par tout processus (aussi ¬ descendant) sntacinummocsussecprodestioncréadeemtnoM Version Janvier 2008 N°275 Tube nommé: exemple d’utilisation (1)
Version Janvier 2008
ère
N°276
Tube nommé: exemple d’utilisation (2) ème
7
Version Janvier 2008
mkfifo: tube nommé
Nom fichier
Protection
Création d’un tube nommé (FIFO) Masque de protection: mode & ¬ umask Utilisation appels systèmes pour fichier ordinaire Exemple :dup2,reda,write,fcntletc,. Mais pasleske Férifo(1)misenebutudfkmcevact:enqunioatré œuvreavecmkfifo(2)
Version Janvier 2008
Utilisation d’un tube nommé
N°277
N°278
open: ture en mode O W _p.esRONLRO(rYtsboluqODLN)Yequ’àceqantejusutaunu’reuverneou pérc_oricteussusouvrelemêmeFIFOenlecture(resp.re). Si l’ouverture est en mode O ou si l’option RDWR estONONBLOCK,alorsl’ouv_ertureestnonbloqu_ante.⇒l’ouverture d’un FIFO peut provoquer un « rendez-vous » entre 2 processus ! writeetread u: même comportement un tube anonyme q e pour Version Janvier 2008 N°279 Tube nommé: Exemple d'utilisation Fichier fifo.h: #include type.h stat.h errno.h extern in errno; #define FIFO1 "/tmp/fifo.1" ##ddeeffiinneePFIEFROM2S"/t0m6p6/6fifo.2"/tmp/fifo.1 client erveur Fichier client: i#itncmluaidne(")fi{fo.h"pmf/fi.o2/t n int readfd, writefd; if ( (writefd =open(FIFO1, 1)) < 0) erreur; if ( (readfd =open(FIFO2, 0)) < 0) erreur; client(readfd, writefd); close(readfd);close(writefd); }
8
Version Janvier 2008
Tube nommé: Exemple d'utilisation
Fichier serveur: #include "fifo.h" int main () { int readfd, writefd; if ( (mkfifo(FIFO1, PERMS)) < 0 &&(errno!=EEXIST))unlink+err;eu if ( (mkfifo(FIFO2, PERMS)) < 0 && (errno != EEXIST)) er;eru if ( (writefd =open(FIFO1, 1)) < 0) er;eur if ( (readfd =open(FIFO2, 0)) < 0) er;rue server(readfd, writefd); close(readfd);close(writefd); if (unlink(FIFO1) < 0) erreur; if (unlink(FIFO2) < 0) erreur; }