Altra roba connessa con le pipe
[gapil.git] / ipc.tex
1 \chapter{La comunicazione fra processi}
2 \label{cha:IPC}
3
4
5 Uno degli aspetti fondamentali della programmazione in un sistema unix-like è
6 la comunicazione fra processi. In questo capitolo affronteremo solo i
7 meccanismi più elementari che permettono di mettere in comunicazione processi
8 diversi, come quelli tradizionali che coinvolgono \textit{pipe} e
9 \textit{fifo} e i meccanismi di intercomunicazione di System V.
10
11 Tralasceremo invece tutte le problematiche relative alla comunicazione
12 attraverso la rete (e le relative interfacce) che saranno affrontate in
13 dettaglio in un secondo tempo.  Non affronteremo invece meccanismi più
14 complessi ed evoluti come le RPC (\textit{Remote Procedure Calls}) e CORBA
15 (\textit{Common Object Request Brocker Architecture}) che in genere sono
16 implementati con un ulteriore livello sopra i meccanismi elementari.
17
18
19
20 \section{La comunicazione fra processi tradizionale}
21 \label{sec:ipc_unix}
22
23 Il primo meccanismo di comunicazione fra processi usato dai sistemi unix-like,
24 e quello che viene correntemente usato di più, è quello delle \textit{pipe},
25 che sono una delle caratteristiche peculiari del sistema, in particolar modo
26 dell'interfaccia a linea di comando. In questa sezione descriveremo le sue
27 basi, le funzioni che ne gestiscono l'uso e le varie forme in cui si è
28 evoluto.
29
30
31 \subsection{Le \textit{pipe} standard}
32 \label{sec:ipc_pipes}
33
34 Le \textit{pipe} nascono sostanzialmente con Unix, e sono il primo, e tuttora
35 uno dei più usati, meccanismi di comunicazione fra processi. Si tratta in
36 sostanza di uno speciale tipo di file descriptor, più precisamente una coppia
37 di file descriptor,\footnote{si tenga presente che le pipe sono oggetti creati
38   dal kernel e non risiedono su disco.}  su cui da una parte si scrive e da
39 un'altra si legge. Si viene così a costituire un canale di comunicazione
40 tramite i due file descriptor, nella forma di un \textsl{tubo} (da cui il
41 nome) in cui in genere un processo immette dati che poi arriveranno ad un
42 altro.
43
44 La funzione che permette di creare una pipe è appunto \func{pipe}; il suo
45 prototipo è:
46 \begin{prototype}{unistd.h}
47 {int pipe(int filedes[2])} 
48   
49 Crea una coppia di file descriptor associati ad una pipe.
50   
51   \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
52     errore, nel qual caso \var{errno} potrà assumere i valori \macro{EMFILE},
53     \macro{ENFILE} e \macro{EFAULT}.}
54 \end{prototype}
55
56 La funzione restituisce una coppia di file descriptor nell'array
57 \param{filedes}; il primo aperto in lettura ed il secondo in scrittura. Il
58 concetto di funzionamento di una pipe è relativamente semplice, quello che si
59 scrive nel file descriptor aperto in scrittura viene ripresentato tale e quale
60 nel file descriptor aperto in lettura, da cui può essere riletto.
61
62 I file descriptor infatti non sono connessi a nessun file reale, ma ad un
63 buffer nel kernel, la cui dimensione è specificata dalla costante
64 \macro{PIPE\_BUF}, (vedi \secref{sec:sys_file_limits}); lo schema di
65 funzionamento di una pipe è illustrato in \figref{fig:ipc_pipe_singular}, in
66 cui sono illustrati i due capi della pipe, associati a ciascun file
67 descriptor, con le frecce che indicano la direzione del flusso dei dati
68 attraverso la pipe.
69
70 \begin{figure}[htb]
71   \centering
72   \includegraphics[height=5cm]{img/pipe}
73   \caption{Schema della struttura di una pipe.}
74   \label{fig:ipc_pipe_singular}
75 \end{figure}
76
77 Chiaramente creare una pipe all'interno di un processo non serve a niente; se
78 però ricordiamo quanto esposto in \secref{sec:file_sharing} riguardo al
79 comportamento dei file descriptor nei processi figli, è immediato capire come
80 una pipe possa diventare un meccanismo di intercomunicazione. Un processo
81 figlio infatti condivide gli stessi file descriptor del padre, compresi quelli
82 associati ad una pipe (secondo la situazione illustrata in
83 \figref{fig:ipc_pipe_fork}). In questo modo se uno dei processi scrive su un
84 capo della pipe, l'altro può leggere.
85
86 \begin{figure}[htb]
87   \centering
88   \includegraphics[height=5cm]{img/pipefork}
89   \caption{Schema dell'uso di una pipe come mezzo di comunicazione fra
90   processo attraverso una \func{fork}.}
91   \label{fig:ipc_pipe_fork}
92 \end{figure}
93
94 Tutto ciò ci mostra come sia immediato realizzare un meccanismo di
95 comunicazione fra processi attraverso una pipe, utilizzando le ordinarie
96 proprietà dei file, ma ci mostra anche qual'è il principale\footnote{Stevens
97   in \cite{APUE} riporta come limite anche il fatto che la comunicazione è
98   unidirezionale, in realtà questo è un limite facilmente superabile usando
99   una coppia di pipe.} limite nell'uso delle pipe. È necessario infatti che i
100 processi possano condividere i file descriptor della pipe, e per questo essi
101 devono comunque derivare da uno stesso processo padre che ha aperto la pipe,
102 o, più comunemente, essere nella relazione padre/figlio.
103
104
105
106 \subsection{Un esempio dell'uso delle pipe}
107 \label{sec:ipc_pipe_use}
108
109 Per capire meglio il funzionamento di una pipe faremo un esempio di quello che
110 è il loro uso più comune, analogo a quello effettuato della shell, e che
111 consiste nell'inviare l'output di un processo (lo standard output) sull'input
112 di un'altro. Realizzaremo il programma nella forma di un
113 \textit{cgi}\footnote{NdA, inserire una breve descrizione di cosa è un cgi.}
114 per apache, che genera una immagine JPEG di un codice a barre, specificato
115 come parametro di input.
116
117 Un programma che deve essere eseguito come \textit{cgi} per apache deve
118 rispondere a delle caratteristiche specifiche, esso infatti non viene lanciato
119 da una shell, ma dallo stesso web server, alla richiesta di una specifica URL
120 che di solito ha la forma:
121 \begin{verbatim}
122 http://www.sito.it/cgi-bin/programma?parametro
123 \end{verbatim}
124 ed il risultato dell'elaborazione deve essere presentato (con una intestazione
125 che ne descrive il mime-type) sullo standard output, in modo che apache possa
126 reinviarlo al browser che ha effettuato la richiesta.
127
128
129 Per fare questo useremo in sequenza i programmi \cmd{barcode} e \cmd{gs}, il
130 primo infatti è in grado di generare immagini postscript di codici a barre
131 corrispondenti ad una qualunque stringa, mentre il secondo serve per poter
132 effettuare la conversione della stessa immagine in formato JPEG.
133
134 Si potrebbe obiettare che sarebbe molto più semplice salvare il risultato
135 intermedio su un file temporaneo. Questo però non tiene conto del fatto che il
136 \textit{cgi} deve poter gestire più richieste in concorrenza, e si avrebbe una
137 evidente race condition in caso di accesso simultaneo a detto
138 file.\footnote{la questione potrebbe essere evitata creando prima dei file
139   temporanei, da comunicare poi ai vari sotto-processi, da cancellare alla
140   fine dell'esecuzione; ma a questo punto avremmo perso tutta la semplicità.}
141 L'uso di una pipe invece permette di risolvere il problema in maniera semplice
142 ed elegante.
143
144 Il programma ci servirà anche come esempio dell'uso di alcune delle funzioni
145 di manipolazione dei file descriptor, come \func{dup} e \func{dup2}, viste in
146 \secref{sec:file_dup}; è attraverso queste funzioni che è possibile dirottare
147 gli stream standard dei processi (che abbiamo visto in
148 \secref{sec:file_std_descr} e \secref{sec:file_std_stream}) sulla pipe. Le
149 sezioni significative del programma è riportato in
150 \figref{fig:ipc_barcode_code}, il codice è disponibile nel file
151 \file{BarCode.c} nella directory dei sorgenti.
152
153
154 \begin{figure}[!htb]
155   \footnotesize \centering
156   \begin{minipage}[c]{15cm}
157     \begin{lstlisting}{}
158 int main(int argc, char *argv[], char *envp[])
159 {
160     ...
161     /* create two pipes to handle process communication */
162     if ( (retval = pipe(pipein)) ) {
163         WriteMess("input pipe creation error");
164         exit(0);        
165     }
166     if ( (retval = pipe(pipeout)) ) {
167         WriteMess("output pipe creation error");
168         exit(0);        
169     }    
170     /* First fork: use child to run barcode program */
171     if ( (pid = fork()) == -1) {          /* on error exit */
172         WriteMess("child creation error");
173         exit(0);        
174     }
175     /* if child */
176     if (pid == 0) {
177         close(pipein[1]);                /* close pipe write end  */
178         dup2(pipein[0], STDIN_FILENO);   /* remap stdin to pipe read end */
179         close(pipeout[0]);
180         dup2(pipeout[1], STDOUT_FILENO); /* remap stdout in pipe output */
181         execlp("barcode", "barcode", size, NULL); //"-o", "-",  NULL);
182     } 
183     close(pipein[0]);                    /* close input side of input pipe */
184     write(pipein[1], argv[1], strlen(argv[1]));  /* write parameter to pipe */
185     close(pipein[1]);                    /* closing write end */
186     waitpid(pid, NULL, 0);               /* wait child completion */
187     /* Second fork: use child to run ghostscript */
188     if ( (pid = fork()) == -1) {          /* on error exit */
189         WriteMess("child creation error");
190         exit(0);
191     }
192     /* second child, convert PS to JPEG  */
193     if (pid == 0) {                     
194         close(pipeout[1]);              /* close write end */
195         dup2(pipeout[0], STDIN_FILENO); /* remap read end to stdin */
196         /* send mime type */
197         write(STDOUT_FILENO, content, strlen(content));
198         execlp("gs", "gs", "-q", "-sDEVICE=jpeg", "-sOutputFile=-", "-", NULL);
199     }
200     /* still parent */
201     close(pipeout[1]); 
202     waitpid(pid, NULL, 0);
203     exit(0);
204 }
205     \end{lstlisting}
206   \end{minipage} 
207   \normalsize 
208   \caption{Codice del \textit{cgi-bin} \cmd{BarCode}.}
209   \label{fig:ipc_barcode_code}
210 \end{figure}
211
212 Il primo passo (\texttt{\small 4--12}) è quello di creare le due pipe che
213 servono per la comunicazione fra i due programmi che verranno utilizzati per
214 produrre il codice a barre; si ha cura di controllare la riuscita della
215 chiamata, inviando in caso di errore un messaggio invece dell'immagine
216 richiesta.\footnote{la funzione \func{WriteMess}, non è riportata in
217   \ref{fig:ipc_barcode_code}, ma si incarica semplicemente di formattare
218   l'uscita, aggiungendo un \textit{mime type}, in modo che possa essere
219   interpretata direttamente da un browser.}
220
221 Una volta create le pipe il programma può creare (\texttt{\small 13-17}) il
222 primo processo figlio, che si incaricherà (\texttt{\small 19--25}) di eseguire
223 il programma \cmd{barcode}: quest'ultimo funziona ricevendo dallo standard
224 input la stringa da convertire nell'immagine postscript del codice a barre,
225 che sarà scritta sullo standard output.
226
227 Per utilizzare queste caratteristiche il primo figlio chiude (\texttt{\small
228   20}) il capo aperto in scrittura della prima pipe, dato che userà il capo
229 aperto in lettura per ricevere dal padre la stringa da codificare; per far
230 questo collega (\texttt{\small 21}) il capo in lettura della pipe allo
231 standard input usando \func{dup2}. Dato che \cmd{barcode} scrive l'immagine
232 postscript del codice a barre sullo standard output per poter effettuare una
233 ulteriore redirezione il capo in lettura della seconda pipe viene chiuso
234 (\texttt{\small 22}) mentre il capo in scrittura viene collegato allo standard
235 output (\texttt{\small 23}).  
236
237 In questo modo all'esecuzione (\texttt{\small 25}) di \cmd{barcode} (cui si
238 passa in \var{size} la dimensione per l'immagine) quest'ultimo leggerà la
239 stringa da codificare che gli viene inviata dal padre dalla prima pipe e
240 scriverà l'immagine postscript del codice a barre sulla seconda.
241
242 Dall'altra parte il processo padre prima chiude (\texttt{\small 26}) il capo
243 inutilizzato della prima pipe (quello in input), poi scrive (\texttt{\small
244   27}) la stringa da convertire sul capo in output così che \cmd{barcode}
245 possa riceverla dallo standard input; a questo punto l'uso della prima pipe è
246 finito ed essa può essere definitivamente chiusa (\texttt{\small 28}), si
247 attende poi (\texttt{\small 29}) che l'esecuzione di \cmd{barcode} sia
248 completata.
249
250 Alla conclusione della sua esecuzione \cmd{barcode} avrà effettuato inviato
251 l'immagine postscript del codice a barre sul capo in scrittura della seconda
252 pipe; a questo punto si può eseguire la seconda conversione, da PS a JPEG,
253 usando il programma \cmd{gs}. Per questo si crea (\texttt{\small 30--34}) un
254 secondo processo figlio, che poi (\texttt{\small 35--42}) eseguirà questo
255 programma leggendo l'immagine postscript creata da \cmd{barcode} sullo
256 standard input per convertirla in JPEG.
257
258 Per fare tutto ciò il secondo figlio anzitutto chiude (\texttt{\small 37}) il
259 capo in scrittura della seconda pipe, e collega (\texttt{\small 38}) il capo
260 in lettura allo standard input. Per poter formattare l'output del programma in
261 maniera utilizzabile da un browser, si provvede anche \texttt{\small 40}) alla
262 scrittura dell'apposita stringa di mime-type in testa allo standard output. A
263 questo punto si può invocare \texttt{\small 41}) il programma \cmd{gs},
264 provvedendo gli appositi switch che consentono di leggere il file da
265 convertire dallo standard input, ed inviare la conversione sullo standard
266 output.
267
268 Per concludere le operazioni il processo padre chiude \texttt{\small 44}) il
269 capo in scrittura della seconda pipe, e attende la conclusione del figlio
270 \texttt{\small 45}), per poi uscire \texttt{\small 46}). Si tenga conto che,
271 l'operazione di chiudere il capo in scrittura della seconda pipe è necessaria,
272 infatti non chiudendola \cmd{gs}, che legge il suo stardard input da detta
273 pipe, resterebbe bloccato in attesa di ulteriore input (l'unico modo che un
274 programma ha per sapere che l'input è terminato è rilevare che lo standard
275 input è stato chiuso), e la \func{wait} non ritornerebbe. 
276
277
278 \subsection{Le funzioni \func{popen} e \func{pclose}}
279 \label{sec:ipc_popen}
280
281 Come si è visto la modalità più comune di utilizzo di una pipe è quella di
282 utilizzarla per fare da tramite fra output ed input di due programmi invocati
283 in sequenza; per questo motivo lo standard POSIX.2 ha introdotto due funzioni
284 che permettono di sintetizzare queste operazioni. La prima di esse si chiama
285 \func{popen} ed il suo prototipo è:
286 \begin{prototype}{stdio.h}
287 {FILE *popen(const char *command, const char *type)}
288
289 Esegue il programma \param{command}, di cui, a seconda di \param{type},
290 restituisce, lo standard input o lo standard output nella pipe collegata allo
291 stream restituito come valore di ritorno.
292   
293 \bodydesc{La funzione restituisce l'indirizzo dello stream associato alla pipe
294   in caso di successo e \macro{NULL} per un errore, nel qual caso \var{errno}
295   potrà assumere i valori relativi alle sottostanti invocazioni di \func{pipe}
296   e \func{fork} o \macro{EINVAL} se \param{type} non è valido.}
297 \end{prototype}
298 \noindent e serve per semplificare l'uso di \func{pipe}. 
299
300 La funzione crea una pipe, esegue una \func{fork}, ed invoca il programma
301 \param{command} attraverso la shell (in sostanza esegue \file{/bin/sh} con il
302 flag \code{-c}); l'argomento \param{type} deve essere una stringa \verb|"w"| o
303 \verb|"r"|, per indicare se la pipe sarà collegata allo standard input o allo
304 standard output del comando invocato.
305
306 La funzione restituisce il puntatore allo stream associato alla pipe creata,
307 che sarà aperto in sola lettura (e quindi associato allo standard output del
308 programma indicato) in caso si sia indicato \code{"r"}, o in sola scrittura (e
309 quindi associato allo standard input) in caso di \code{"w"}.
310
311 Lo stream restituito da \func{popen} è identico a tutti gli effetti ai file
312 standard visti in \secref{cha:files_std_interface}, e viene sempre aperto in
313 modalità \textit{fully-buffered} (vedi \secref{sec:file_buffering}); l'unica
314 differenza è che deve essere chiuso dalla seconda delle due funzioni,
315 \func{pclose}, il cui prototipo è:
316 \begin{prototype}{stdio.h}
317 {int pclose(FILE *stream)}
318
319 Chiude il file \param{stream}, restituito da una prededente \func{popen}
320 attendendo la terminazione del processo ad essa associato.
321   
322 \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
323   errore; nel quel caso il valore di \func{errno} deriva dalle sottostanti
324   chiamate.}
325 \end{prototype}
326 \noindent che si incarica anche di attendere la conclusione del processo
327 creato dalla precedente \func{popen}.
328
329 Per illustrare l'uso di queste due funzioni riprendiamo l'esempio in
330 \figref{fig:ipc_barcode_code}: esso per quanto funzionante, è piuttosto
331 complesso; inoltre nella pratica sconta un problema di \cmd{gs} che non è in
332 grado\footnote{nella versione GNU Ghostscript 6.53 (2002-02-13).} di
333 riconoscere correttamente l'encapsulated postscript, per cui tutte le volte
334 generata una pagina intera, invece che una semplice figura.  Se si vuole
335 generare una immagine di dimensioni corrette si deve allora ricorrere ad
336 ulteriore programma, \cmd{epstopsf}, per convertire in PDF il file EPS
337 generato da \cmd{barcode}. Utilizzando un file in PDF invece, \cmd{gs} esegue
338 la conversione rispettando le dimensioni originarie del codice a barre.
339
340
341
342
343
344 \subsection{Le \textit{pipe} con nome, o \textit{fifo}}
345 \label{sec:ipc_named_pipe}
346
347 Come accennato in \secref{sec:ipc_pipes} il problema delle \textit{pipe} è che
348 esse possono essere utilizzate solo da processi con un progenitore comune o
349 nella relazione padre/figlio; per superare questo problema lo standard POSIX.1
350 ha definito dei nuovi oggetti, le \textit{fifo}, che hanno le stesse
351 caratteristiche delle pipe, ma invece che essere struttura interne del kernel
352 visibili solo attraverso un file descriptor comune, possono essere viste
353 attraverso un inode che risiede sul filesystem.
354
355
356 Abbiamo già accennato in \secref{sec:file_mknod}
357
358 che invece possono risiedere
359 sul filesystem, e che i processi possono usare per le comunicazioni senza
360 dovere per forza essere in relazione diretta.
361
362
363
364
365 Per poter superare il problema delle \textit{pipe}, illustrato in
366 \secref{sec:ipc_pipes}, che ne consente l'uso solo fra processi con un
367 progenitore comune o nella relazione padre/figlio,
368   
369 \section{La comunicazione fra processi di System V}
370 \label{sec:ipc_sysv}
371
372 Per ovviare ai vari limiti dei meccanismo tradizionale di comunicazione fra
373 processi visto in \secref{sec:ipc_unix}, nello sviluppo di System V vennero
374 introdotti una serie di nuovi oggetti e relative interfacce che garantissero
375 una maggiore flessibilità; in questa sezione esamineremo quello che viene
376 ormai chiamato il \textit{System V Inter-Process Comunication System}, più
377 comunemente noto come \textit{SystemV IPC}.
378  
379
380 \subsection{Code di messaggi}
381 \label{sec:ipc_messque}
382
383 Il primo oggetto introdotto dal \textit{SystemV IPC} è quello delle code di
384 messaggi.
385
386 \subsection{Semafori}
387 \label{sec:ipc_semaph}
388
389 Il secondo oggetto introdotto dal \textit{SystemV IPC} è quello dei semafori.
390
391
392 \subsection{Memoria condivisa}
393 \label{sec:ipc_shar_mem}
394
395 Il terzo oggetto introdotto dal \textit{SystemV IPC} è quello della memoria
396 condivisa.
397
398 %%% Local Variables: 
399 %%% mode: latex
400 %%% TeX-master: "gapil"
401 %%% End: