Академический Документы
Профессиональный Документы
Культура Документы
2012-2013
Introduction
Quelques informations avant de commencer
La communication par tubes
Principe
Les tubes et le shell
Tubes anonymes
Spcificits
Operations sur les tubes anonymes
Mise en oeuvre
Exercice : redirection de lentre
Les tubes nomms
Spcificits
Operations sur les tubes nomms
Mise en oeuvre
Exercice : client-server
Rgles de fonctionnement
I
La fonction man du shell doit, tant que faire se peut, tre utilise avant de poser
une question par email ou en TP.
References
I
Imprimez le code des examples pour suivre le commentaire pendant le cours. Le code
est souvent trop long pour tre affich sur les slides.
Introduction
I
Les processus peuvent avoir besoin de communiquer entre eux pour changer des
donnes.
Linux offre diffrents outils de communication aux processus utilisateurs :
les tubes anonymes (pipes) ou nomms ; les files de messages (message queues) ; la
mmoire partage.
Les tubes sont grs par le systme de gestion de fichiers (cf. cours 4).
Sockets, messages
La gestion des donnes dans le tube est lie au mode daccs squentiel.
Un tube a une capacit finie qui est celle du tampon qui lui est allou.
Cette capacit est dfinie par la constante symbolique PIPE_BUF dfinie dans
<limits .h> .
Un tube peut donc tre plein et de fait amener les processus crivains
sendormir en attendant de pouvoir raliser leur criture : opration bloquante.
Principe
I
Un tube est une tuyau dans lequel un processus peut crire des donnes quun
autre processus peut lire.
Un processus ne peut donc tre la fois crivain et lecteur dun mme tube.
les enregistrements sont traits dans lordre o ils se trouvent dans le fichier
(octet par octet) ;
mode daccs simple, pas forcment pratique, fichier accessible en lecture seule ou
en criture seule.
I
I
Il suffit donc denvoyer la sortie de ls l vers lentre de wc l. Ceci peut tre fait
avec un pipe : ls l | wc l.
Read/write : data written to the pipe by one process can be read by another
process
A pipe has no name : to use it, both ends (processes) must inherit it from the
single process that created the pipe
dmesg
dmesg | less
dmesg | grep disabled | grep IO
$ ls -l | grep Makefile
-rw-rw-r-- 1 icub icub 306 Sep 19 18:22 Makefile
$ dmesg | grep nouveaufb
[
17.959472] fb1: nouveaufb frame buffer device
Fifo
I
Similar to a pipe in its purpose, but substantially different, since it is a special file
Any process can open a fifo for reading/writing in the same way as an ordinary
file (assuming file permissions allow it)
Once they are opened (different way !) the semantics fro read/write is the same
Writing to a pipe/fifo without reader fails (SIGPIPE signal and error EPIPE are
generated)
Differences :
Name
Creation
Access
Reading
Writing
pipe
no (anonymous)
pipe
through file descriptors
file descriptor [0]
file descriptor [1]
fifo
yes (path)
mkfifo
through path in file system
O_RDONLY
O_WRONLY
Cration
I
Un tube anonyme est cr par appel la fonction pipe() dont les prototype est
int pipe ( int desc [2]); (dfini dans #include <unistd.h> ).
Un fichier physique est associ au tube mais aucun bloc de donnes ne lui
correspond.
Les donnes transitant dans un tube sont places dans un tampon allou dans la
mmoire centrale.
Tout processus ayant connaissance du descripteur en lecture desc [0] dun tube
peut lire dans ce dernier (on peut donc avoir plusieurs processus lecteurs dans un
mme tube).
Tout processus ayant connaissance du descripteur en criture desc [1] dun tube
peut crire dans ce dernier (on peut donc avoir plusieurs processus crivains dans
un mme tube).
Cette absence de nom induit que ce type de tube ne peut tre manipul que par
des processus ayant connaissance des deux descripteurs (lecture/criture) associs
au tube.
I
I
I
Lecture
I
Fermeture
I
Un tube anonyme est considr comme ferm lorsque tous les descripteurs en
lecture et en criture existants sur ce tube sont ferms.
I
I
I
si le tube nest pas vide et contient taille caractres, read extrait du tube
min(taille, count) caractres qui sont lus et placs ladresse buf ;
si le tube est vide et que le nombre dcrivains est non nul, la lecture est bloquante et le
processus lecteur est mis en sommeil jusqu ce que le tube ne soit plus vide ;
si le tube est vide et que le nombre dcrivains est nul, la fin du fichier est atteinte et le
nombre de caractres rendu est nul.
Lopration de lecture peut tre rendue non bloquante par un appel la fonction
de manipulation des descripteurs de fichier fcntl () :
fcntl (desc [0], F_SETFL, O_NONBLOCK); .
Recap
Ecriture
I
I
I
#include <unistd.h>
int pipe(int filedes[2]);
int close(int fd);
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
si le nombre de lecteurs dans le tube est nul alors une erreur est gnre et le signal
SIGPIPE est dlivr au processus crivain qui se termine.
si le nombre de lecteurs dans le tube est non nul, lopration dcriture est bloquante
jusqu ce que count caractres aient effectivement t crits dans le tube ;
Dans le cas o le nombre de caractres count crire dans le tube est < la constante
symbolique PIPE_BUF (4096 octets), lcriture des count caractres est atomique :
les count caractres sont tous crits les uns la suite des autres dans le tube.
Dans le cas o le nombre de caractres count crire dans le tube est > la
constante symbolique PIPE_BUF , lcriture des count caractres peut tre
arbitrairement dcoupe par le systme.
Mise en oeuvre
Cas typique
I
Le processus pre fork () (cration dun fils qui connat donc les descripteurs du
tube) ;
Les descripteurs en lecture et criture sont utilisables par les deux processus.
Chacun ferme le descripteur qui lui est inutile : par exemple le pre ferme le
descripteur en criture et le fils le descripteur en lecture.
Lorsquun tube est cr, le processus associ cette cration est potentiellement
crivain ou lecteur.
La logique veut donc quon ne se dclare pas lecteur ou crivain mais plutt
quon ferme avec close () le descripteur correspondant au mode de
fonctionnement qui ne nous intresse pas.
# include
# include
# include
# include
# include
# include
return 0;
TEST
**** pipefork.c ****
Output :
icub@eva:~/progsys/cours/c5/code$ ./pipe1
Child: writing the value 1786065064
Father: reading the value 1786065064
Write a program that creates a pipe, then forks to create a child. After the fork each
process closes the descriptors that it does not need.
I
The father process writes the string received as command-line parameter in the
pipe (argv[1])
The child reads the string (note ! byte per byte !) from the pipe and print it on
stdout
Example :
$ ./test1 "luke i am your father"
luke i am your father
Les tubes nomms sont galement grs par le systme de gestion de fichiers.
Le fichier associ possde un nom et le tube est donc accessible par tout
processus connaissant ce nom et disposant des droits daccs au tube.
Les tubes nomms permettent donc des processus sans lien de parent de
communiquer selon un mode squentiel.
Les donnes transitant dans un tube nomm sont donc places dans un tampon
allou dans la mmoire centrale.
Note : FIFO special files are indicated by ls l with the file type p
icub@eva:/tmp/fifo$ ls
icub@eva:/tmp/fifo$ mkfifo serefifo
icub@eva:/tmp/fifo$ ls -l
total 0
prw-rw-r-- 1 icub icub 0 Sep 26 15:15 serefifo
Cration
I
Lecture / criture
tube.
mode permet de spcifier les droits daccs associs au tube (cf. cours 4).
Fermeture
I
Ouverture
I
Destruction
I
Recap
I
I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# include
# include
# include
# include
# include
# include
# include
# include
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
TEST
I
Since the server creates the fifos, once we launch the server :
$ ./fifo_server
we can see the fifos by checking their path :
icub@eva:/tmp$ ls -l
prw-rw-r-- 1 icub
icub
prw-rw-r-- 1 icub
icub
Note that in this example, the client assumes the fifos have already been created.
This is what happens if we launch the client first :
$ ./fifo_client
client: cant open FIFO1 to write
Beware ! If we accidentally press CTRL+C on the server, fifos are not destroyed
properly... check /tmp/ to see if they were closed properly.
Modify the client-server example so that client and server do really something, e.g.
exchange data :
I
the client connects to the server, sends an integer, and waits for the server to
reply with another integer
the server wait for a client connection, receives an integer, perform some
processing on this integer (for example, add +10), then send the result to the
client
The server :
$ ./fifo_server
server: wait for incoming connection
server: read 42, sent 52
The client :
$ ./fifo_client
client: sent 42
client: wait for server reply
client: read 52
Questions ?