Initiation à la Programmation
Système
Chapitre : Tubes
Communication entre processus : les
tubes
• Un tube est un canal de communication FIFO (First In, First Out).
• Les caractères lus sont les caractères les plus anciennement écrits.
• Le programmeur ne peut pas déplacer la tête de lecture/écriture.
• Elle est gérée par le système pour assurer l’aspect FIFO.
• L’appel pipe permet de créer un tube.
int pipe(int descr [2]);
ouvre un tube et initialise 2 descripteurs :
• descr[0] référence l’« extrémité » lecture du tube,
• descr[1] référence l’« extrémité » écriture du tube.
Les tubes
char buf[4] ;
int descr[2] ;
pipe(descr) ;
descr[0] descr[1]
write(descr[1], "ABC", strlen("ABC")) ;
write(descr[1], "0123", strlen("0123")) ;
read(descr[0], buf, 4) ; // buf contient {’A’,’B’,’C’,’0’}
read(descr[0], buf, 4) ; // buf contient {’1’,’2’,’3’,’0’}
read(descr[0], buf, 4) ; //
Les tubes
Un processus est
• écrivain (potentiel) sur le tube d s’il a le
descripteur d[1] ouvert.
• lecteur (potentiel) sur le tube d s’il a le
descripteur d[0] ouvert.
Les tubes
• La lecture sur tube vide
– renvoie 0 s’il n’y a plus d’écrivains,
– provoque la mise en sommeil du processus sinon.
• L’écriture sur un tube qui n’a plus de lecteurs
provoque la génération d’un signal SIGPIPE (qui
normalement termine le processus).
• Un tube a une taille maximale finie. Écriture sur tube
plein avec
lecteurs =⇒ sommeil.
• Écriture de taille 6 PIPE_BUF : sans entrelacements
avec d’autres E/S sur le tube.
Les tubes
#include <stdio.h>
#include <unistd.h> Exemple
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
int main(void){
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[80];
pipe(fd);
childpid = fork();
if(childpid == 0){
close(fd[0]);
write(fd[1], string, (strlen(string)+1));
exit(0);
}
else{
close(fd[1]);
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}
return(0);
}
Tubes nommés
• Les tubes sont bien adaptés pour transmettre de
l’information entre processus ayant des descripteurs en
commun.
• Pour des processus sans lien de parenté : tubes
nommés.
int mkfifo (const char *chemin , mode_t mode);
• Ces tubes apparaissent dans le système de fichiers.
• mode contient uniquement des bits de permissions,
utilisés avec la valeur d’umask pour la création.
• stat() donne le type S_ISFIFO.
Tubes nommés
• L’appel open est bloquant pour un tube nommé.
• Un processus demandant l’ouverture en lecture
attend l’arrivée d’écrivains, et vice-versa.
• Si deux processus veulent dialoguer dans les
deux sens
• On peut rendre l’ouverture non bloquante
(O_NONBLOCK dans le mode d’ouverture).
Dans ce cas, une demande en écriture sans
lecteurs échoue.
Exemple
emet.c recoit.c
#include <stdio.h> #include <stdio.h>
#include <sys/fcntl.h> #include <sys/fcntl.h>
int main(void) int main(void) {
{ char buf[50] ;
char string[] = "Hello, int fd ;
world!\n"; fd=open("toto",O_RDONLY) ;
int fd ; read(fd, buf,sizeof(buf));
fd=open("toto",O_WRONLY) ; printf("%d fin lecture:%s",
write(fd, string, getpid(),buf);
(strlen(string)+1)); }
printf("%d fin ecriture :",
getpid());
}
$/etc/mknod toto p
$recoit&
$emet