Correzioni
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 3c30111cebf747b7316715bdcc672a4e373b441c..e0fef633d8d75c4f75cb8cb805f5aad3f10f3a41 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -6,7 +6,7 @@ Uno degli aspetti fondamentali della programmazione in un sistema unix-like 
 la comunicazione fra processi. In questo capitolo affronteremo solo i
 meccanismi più elementari che permettono di mettere in comunicazione processi
 diversi, come quelli tradizionali che coinvolgono \textit{pipe} e
-\textit{fifo} e i meccanismi di intercomunicazione di System V.
+\textit{fifo} e i meccanismi di intercomunicazione di System V e quelli POSIX.
 
 Tralasceremo invece tutte le problematiche relative alla comunicazione
 attraverso la rete (e le relative interfacce) che saranno affrontate in
@@ -20,12 +20,11 @@ implementati con un ulteriore livello sopra i meccanismi elementari.
 \section{La comunicazione fra processi tradizionale}
 \label{sec:ipc_unix}
 
-Il primo meccanismo di comunicazione fra processi usato dai sistemi unix-like,
-e quello che viene correntemente usato di più, è quello delle \textit{pipe},
-che sono una delle caratteristiche peculiari del sistema, in particolar modo
-dell'interfaccia a linea di comando. In questa sezione descriveremo le sue
-basi, le funzioni che ne gestiscono l'uso e le varie forme in cui si è
-evoluto.
+Il primo meccanismo di comunicazione fra processi introdotto nei sistemi Unix,
+è quello delle cosiddette \textit{pipe}; esse costituiscono una delle
+caratteristiche peculiari del sistema, in particolar modo dell'interfaccia a
+linea di comando. In questa sezione descriveremo le sue basi, le funzioni che
+ne gestiscono l'uso e le varie forme in cui si è evoluto.
 
 
 \subsection{Le \textit{pipe} standard}
@@ -33,39 +32,36 @@ evoluto.
 
 Le \textit{pipe} nascono sostanzialmente con Unix, e sono il primo, e tuttora
 uno dei più usati, meccanismi di comunicazione fra processi. Si tratta in
-sostanza di uno speciale tipo di file descriptor, più precisamente una coppia
-di file descriptor,\footnote{si tenga presente che le pipe sono oggetti creati
-  dal kernel e non risiedono su disco.}  su cui da una parte si scrive e da
-un'altra si legge. Si viene così a costituire un canale di comunicazione
-tramite i due file descriptor, nella forma di un \textsl{tubo} (da cui il
-nome) in cui in genere un processo immette dati che poi arriveranno ad un
-altro.
-
-La funzione che permette di creare una pipe è appunto \func{pipe}; il suo
-prototipo è:
+sostanza di una una coppia di file descriptor\footnote{si tenga presente che
+  le pipe sono oggetti creati dal kernel e non risiedono su disco.} connessi
+fra di loro in modo che se quanto scrive su di uno si può rileggere
+dall'altro. Si viene così a costituire un canale di comunicazione tramite i
+due file descriptor, nella forma di un \textsl{tubo} (da cui il nome)
+attraverso cui fluiscono i dati.
+
+La funzione che permette di creare questa speciale coppia di file descriptor
+associati ad una \textit{pipe} è appunto \func{pipe}, ed il suo prototipo è:
 \begin{prototype}{unistd.h}
 {int pipe(int filedes[2])} 
   
-Crea una coppia di file descriptor associati ad una pipe.
+Crea una coppia di file descriptor associati ad una \textit{pipe}.
   
   \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
     errore, nel qual caso \var{errno} potrà assumere i valori \macro{EMFILE},
     \macro{ENFILE} e \macro{EFAULT}.}
 \end{prototype}
 
-La funzione restituisce una coppia di file descriptor nell'array
-\param{filedes}; il primo aperto in lettura ed il secondo in scrittura. Il
-concetto di funzionamento di una pipe è relativamente semplice, quello che si
+La funzione restituisce la coppia di file descriptor nell'array
+\param{filedes}; il primo è aperto in lettura ed il secondo in scrittura. Come
+accennato concetto di funzionamento di una pipe è semplice: quello che si
 scrive nel file descriptor aperto in scrittura viene ripresentato tale e quale
-nel file descriptor aperto in lettura, da cui può essere riletto.
-
-I file descriptor infatti non sono connessi a nessun file reale, ma ad un
-buffer nel kernel, la cui dimensione è specificata dalla costante
-\macro{PIPE\_BUF}, (vedi \secref{sec:sys_file_limits}); lo schema di
-funzionamento di una pipe è illustrato in \figref{fig:ipc_pipe_singular}, in
-cui sono illustrati i due capi della pipe, associati a ciascun file
-descriptor, con le frecce che indicano la direzione del flusso dei dati
-attraverso la pipe.
+nel file descriptor aperto in lettura. I file descriptor infatti non sono
+connessi a nessun file reale, ma ad un buffer nel kernel, la cui dimensione è
+specificata dalla costante \macro{PIPE\_BUF}, (vedi
+\secref{sec:sys_file_limits}). Lo schema di funzionamento di una pipe è
+illustrato in \figref{fig:ipc_pipe_singular}, in cui sono illustrati i due
+capi della pipe, associati a ciascun file descriptor, con le frecce che
+indicano la direzione del flusso dei dati.
 
 \begin{figure}[htb]
   \centering
@@ -74,12 +70,12 @@ attraverso la pipe.
   \label{fig:ipc_pipe_singular}
 \end{figure}
 
-Chiaramente creare una pipe all'interno di un processo non serve a niente; se
-però ricordiamo quanto esposto in \secref{sec:file_sharing} riguardo al
-comportamento dei file descriptor nei processi figli, è immediato capire come
-una pipe possa diventare un meccanismo di intercomunicazione. Un processo
-figlio infatti condivide gli stessi file descriptor del padre, compresi quelli
-associati ad una pipe (secondo la situazione illustrata in
+Chiaramente creare una pipe all'interno di un singolo processo non serve a
+niente; se però ricordiamo quanto esposto in \secref{sec:file_sharing}
+riguardo al comportamento dei file descriptor nei processi figli, è immediato
+capire come una pipe possa diventare un meccanismo di intercomunicazione. Un
+processo figlio infatti condivide gli stessi file descriptor del padre,
+compresi quelli associati ad una pipe (secondo la situazione illustrata in
 \figref{fig:ipc_pipe_fork}). In questo modo se uno dei processi scrive su un
 capo della pipe, l'altro può leggere.
 
@@ -92,27 +88,44 @@ capo della pipe, l'altro pu
 \end{figure}
 
 Tutto ciò ci mostra come sia immediato realizzare un meccanismo di
-comunicazione fra processi attraverso una pipe, utilizzando le ordinarie
-proprietà dei file, ma ci mostra anche qual'è il principale\footnote{Stevens
+comunicazione fra processi attraverso una pipe, utilizzando le proprietà
+ordinarie dei file, ma ci mostra anche qual'è il principale\footnote{Stevens
   in \cite{APUE} riporta come limite anche il fatto che la comunicazione è
-  unidirezionale, in realtà questo è un limite facilmente superabile usando
+  unidirezionale, ma in realtà questo è un limite facilmente superabile usando
   una coppia di pipe.} limite nell'uso delle pipe. È necessario infatti che i
 processi possano condividere i file descriptor della pipe, e per questo essi
-devono comunque derivare da uno stesso processo padre che ha aperto la pipe,
-o, più comunemente, essere nella relazione padre/figlio.
+devono comunque derivare da uno stesso processo padre in cui è avvenuta la
+creazione della pipe, o, più comunemente, essere nella relazione padre/figlio.
+
+A differenza di quanto avviene con i file normali, la lettura da una pipe può
+essere bloccante (qualora non siano presenti dati), inoltre se si legge da una
+pipe il cui capo in scrittura è stato chiuso, si avrà la ricezione di un EOF
+(vale a dire che la funzione \func{read} ritornerà restituendo 0).  Se invece
+si esegue una scrittura su una pipe il cui capo in lettura non è aperto il
+processo riceverà il segnale \macro{EPIPE}, e la funzione di scrittura
+restituirà un errore di \macro{EPIPE} (al ritorno del manipolatore, o qualora
+il segnale sia ignorato o bloccato).
+
+La dimensione del buffer della pipe (\macro{PIPE\_BUF}) ci dà inoltre un'altra
+importante informazione riguardo il comportamento delle operazioni di lettura
+e scrittura su di una pipe; esse infatti sono atomiche fintanto che la
+quantità di dati da scrivere non supera questa dimensione. Qualora ad esempio
+si effettui una scrittura di una quantità di dati superiore l'operazione verrà
+effettuata in più riprese, consentendo l'intromissione di scritture effettuate
+da altri processi.
 
 
 \subsection{Un esempio dell'uso delle pipe}
 \label{sec:ipc_pipe_use}
 
-Per capire meglio il funzionamento di una pipe faremo un esempio di quello che
+Per capire meglio il funzionamento delle pipe faremo un esempio di quello che
 è il loro uso più comune, analogo a quello effettuato della shell, e che
 consiste nell'inviare l'output di un processo (lo standard output) sull'input
-di un'altro. Realizzaremo il programma nella forma di un
-\textit{CGI}\footnote{Un CGI (\textit{Common Gateway Interface}) è un programma
-  che permette la creazione dinamica di un oggetto da inserire all'interno di
-  una pagina HTML.}  per apache, che genera una immagine JPEG di un codice a
-barre, specificato come parametro di input.
+di un'altro. Realizzeremo il programma di esempio nella forma di un
+\textit{CGI}\footnote{Un CGI (\textit{Common Gateway Interface}) è un
+  programma che permette la creazione dinamica di un oggetto da inserire
+  all'interno di una pagina HTML.}  per apache, che genera una immagine JPEG
+di un codice a barre, specificato come parametro di input.
 
 Un programma che deve essere eseguito come \textit{CGI} deve rispondere a
 delle caratteristiche specifiche, esso infatti non viene lanciato da una
@@ -126,13 +139,13 @@ che ne descrive il mime-type) sullo standard output, in modo che il web-server
 possa reinviarlo al browser che ha effettuato la richiesta, che in questo modo
 è in grado di visualizzarlo opportunamente.
 
-Per fare questo useremo in sequenza i programmi \cmd{barcode} e \cmd{gs}, il
-primo infatti è in grado di generare immagini postscript di codici a barre
-corrispondenti ad una qualunque stringa, mentre il secondo serve per poter
-effettuare la conversione della stessa immagine in formato JPEG. Usando una
-pipe potremo inviare l'output del primo sull'input del secondo, secondo lo
-schema mostrato in \figref{fig:ipc_pipe_use}, in cui la direzione del flusso
-dei dati è data dalle frecce continue.
+Per realizzare quanto voluto useremo in sequenza i programmi \cmd{barcode} e
+\cmd{gs}, il primo infatti è in grado di generare immagini postscript di
+codici a barre corrispondenti ad una qualunque stringa, mentre il secondo
+serve per poter effettuare la conversione della stessa immagine in formato
+JPEG. Usando una pipe potremo inviare l'output del primo sull'input del
+secondo, secondo lo schema mostrato in \figref{fig:ipc_pipe_use}, in cui la
+direzione del flusso dei dati è data dalle frecce continue.
 
 \begin{figure}[htb]
   \centering
@@ -148,18 +161,19 @@ intermedio su un file temporaneo. Questo per
 \textit{CGI} deve poter gestire più richieste in concorrenza, e si avrebbe una
 evidente race condition in caso di accesso simultaneo a detto
 file.\footnote{il problema potrebbe essere superato determinando in anticipo
-  un nome appropiato per il file temporaneo, che verrebbe utilizzato dai vari
+  un nome appropriato per il file temporaneo, che verrebbe utilizzato dai vari
   sotto-processi, e cancellato alla fine della loro esecuzione; ma a questo le
   cose non sarebbero più tanto semplici.}  L'uso di una pipe invece permette
-di risolvere il problema in maniera semplice ed elegante.
+di risolvere il problema in maniera semplice ed elegante, oltre ad essere
+molto più efficiente, dato che non si deve scrivere su disco.
 
 Il programma ci servirà anche come esempio dell'uso delle funzioni di
 duplicazione dei file descriptor che abbiamo trattato in
 \secref{sec:file_dup}, in particolare di \func{dup2}. È attraverso queste
 funzioni infatti che è possibile dirottare gli stream standard dei processi
 (che abbiamo visto in \secref{sec:file_std_descr} e
-\secref{sec:file_std_stream}) sulla pipe. In \figref{fig:ipc_barcode_code}
-abbiamo riportato il corpo del programm, il cui codice completo è disponibile
+\secref{sec:file_std_stream}) sulla pipe. In \figref{fig:ipc_barcodepage_code}
+abbiamo riportato il corpo del programma, il cui codice completo è disponibile
 nel file \file{BarCodePage.c} che si trova nella directory dei sorgenti.
 
 
@@ -219,7 +233,7 @@ int main(int argc, char *argv[], char *envp[])
   \normalsize 
   \caption{Sezione principale del codice del \textit{CGI} 
     \file{BarCodePage.c}.}
-  \label{fig:ipc_barcode_code}
+  \label{fig:ipc_barcodepage_code}
 \end{figure}
 
 La prima operazione del programma (\texttt{\small 4--12}) è quella di creare
@@ -227,10 +241,10 @@ le due pipe che serviranno per la comunicazione fra i due comandi utilizzati
 per produrre il codice a barre; si ha cura di controllare la riuscita della
 chiamata, inviando in caso di errore un messaggio invece dell'immagine
 richiesta.\footnote{la funzione \func{WriteMess}, non è riportata in
-  \secref{fig:ipc_barcode_code}; essa si incarica semplicemente di formattare
-  l'uscita alla maniera dei CGI, aggiungendo l'opportuno \textit{mime type}, e
-  formattando il messaggio in HTML, in modo che quest'ultimo possa essere
-  visualizzato correttamente da un browser.}
+  \secref{fig:ipc_barcodepage_code}; essa si incarica semplicemente di
+  formattare l'uscita alla maniera dei CGI, aggiungendo l'opportuno
+  \textit{mime type}, e formattando il messaggio in HTML, in modo che
+  quest'ultimo possa essere visualizzato correttamente da un browser.}
 
 Una volta create le pipe, il programma può creare (\texttt{\small 13-17}) il
 primo processo figlio, che si incaricherà (\texttt{\small 19--25}) di eseguire
@@ -285,7 +299,7 @@ capo in scrittura della seconda pipe, e attende la conclusione del figlio
 (\texttt{\small 45}); a questo punto può (\texttt{\small 46}) uscire. Si tenga
 conto che l'operazione di chiudere il capo in scrittura della seconda pipe è
 necessaria, infatti, se non venisse chiusa, \cmd{gs}, che legge il suo
-stardard input da detta pipe, resterebbe bloccato in attesa di ulteriori dati
+standard input da detta pipe, resterebbe bloccato in attesa di ulteriori dati
 in ingresso (l'unico modo che un programma ha per sapere che l'input è
 terminato è rilevare che lo standard input è stato chiuso), e la \func{wait}
 non ritornerebbe.
@@ -332,7 +346,7 @@ funzioni, \func{pclose}, il cui prototipo 
 \begin{prototype}{stdio.h}
 {int pclose(FILE *stream)}
 
-Chiude il file \param{stream}, restituito da una prededente \func{popen}
+Chiude il file \param{stream}, restituito da una precedente \func{popen}
 attendendo la terminazione del processo ad essa associato.
   
 \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
@@ -344,8 +358,8 @@ attendendo la terminazione del processo ad essa associato.
 \func{popen}.
 
 Per illustrare l'uso di queste due funzioni riprendiamo il problema
-precedente: il programma mostrato in \figref{fig:ipc_barcode_code} per quanto
-funzionante, è (volutamente) codificato in maniera piuttosto complessa,
+precedente: il programma mostrato in \figref{fig:ipc_barcodepage_code} per
+quanto funzionante, è (volutamente) codificato in maniera piuttosto complessa,
 inoltre nella pratica sconta un problema di \cmd{gs} che non è in
 grado\footnote{nella versione GNU Ghostscript 6.53 (2002-02-13).} di
 riconoscere correttamente l'encapsulated postscript, per cui deve essere usato
@@ -380,19 +394,19 @@ dimensioni corrette attraverso vari programmi di manipolazione (\cmd{pnmcrop},
 
 In questo caso però occorre eseguire in sequenza ben quattro comandi diversi,
 inviando l'output di ciascuno all'input del successivo, per poi ottenere il
-risultato finale sullo standard output; un caso classico di utilizzazione
+risultato finale sullo standard output: un caso classico di utilizzazione
 delle pipe, in cui l'uso di \func{popen} e \func{pclose} permette di
 semplificare notevolmente la stesura del codice.
 
 Nel nostro caso, dato che ciascun processo deve scrivere il suo output sullo
 standard input del successivo, occorrerà usare \func{popen} aprendo la pipe in
 scrittura. Il codice del nuovo programma è riportato in
-\figref{fig:ipc_barcode2_code}.  Come si può notare l'ordine di invocazione
-dei programmi è l'inverso di quello in cui ci si aspetta vengano
-effettivamente eseguiti. Questo non comporta nessun problema; infatti la
+\figref{fig:ipc_barcode_code}.  Come si può notare l'ordine di invocazione dei
+programmi è l'inverso di quello in cui ci si aspetta che vengano
+effettivamente eseguiti. Questo non comporta nessun problema dato che la
 lettura su una pipe è bloccante, per cui ciascun processo, per quanto lanciato
 per primo, si bloccherà in attesa di ricevere sullo standard input il
-risultato dell'elaborazione del precendente, benchè quest'ultimo venga
+risultato dell'elaborazione del precedente, benchè quest'ultimo venga
 invocato dopo.
 
 \begin{figure}[!htb]
@@ -427,12 +441,6 @@ int main(int argc, char *argv[], char *envp[])
         pclose((pipe[i]));
     }
     exit(0);
-}
-void WriteMess(char *mess)
-{
-    printf("Content-type: text/html\n\n");
-    perror(mess);
-    printf("<br>\n");
 }
     \end{lstlisting}
   \end{minipage} 
@@ -472,63 +480,177 @@ Come accennato in \secref{sec:ipc_pipes} il problema delle \textit{pipe} 
 esse possono essere utilizzate solo da processi con un progenitore comune o
 nella relazione padre/figlio; per superare questo problema lo standard POSIX.1
 ha definito dei nuovi oggetti, le \textit{fifo}, che hanno le stesse
-caratteristiche delle pipe, ma invece che essere struttura interne del kernel
-visibili solo attraverso un file descriptor comune, possono essere viste
-attraverso un inode che risiede sul filesystem.
+caratteristiche delle pipe, ma che invece di essere strutture interne del
+kernel, visibili solo attraverso un file descriptor, sono accessibili
+attraverso un inode che risiede sul filesystem, così che i processi le possono
+usare senza dovere per forza essere in una relazione di \textsl{parentela}.
+
+Utilizzando una \textit{fifo} tutti i dati passeranno, come per le pipe,
+attraverso un apposito buffer nel kernel, senza transitare dal filesystem;
+l'inode allocato sul filesystem serve infatti solo a fornire un punto di
+riferimento per i processi, che permetta loro di accedere alla stessa fifo; il
+comportamento delle funzioni di lettura e scrittura è identico a quello
+illustrato per le pipe in \secref{sec:ipc_pipes}.
+
+Abbiamo già visto in \secref{sec:file_mknod} le funzioni \func{mknod} e
+\func{mkfifo} che permettono di creare una fifo; per utilizzarne una un
+processo non avrà che da aprire il relativo file speciale o in lettura o
+scrittura; nel primo caso sarà collegato al capo di uscita della fifo, e dovrà
+leggere, nel secondo al capo di ingresso, e dovrà scrivere.
+
+Il kernel crea una singola pipe per ciascuna fifo che sia stata aperta, che può
+essere acceduta contemporaneamente da più processi, sia in lettura che in
+scrittura. Dato che per funzionare deve essere aperta in entrambe le
+direzioni, per una fifo di norma la funzione \func{open} si blocca se viene
+eseguita quando l'altro capo non è aperto.
+
+Le fifo però possono essere anche aperte in modalità \textsl{non-bloccante},
+nel qual caso l'apertura del capo in lettura avrà successo solo quando anche
+l'altro capo è aperto, mentre l'apertura del capo in scrittura restituirà
+l'errore di \macro{ENXIO} fintanto che non verrà aperto il capo in lettura.
+
+In Linux\footnote{lo standard POSIX lascia indefinito questo comportamento.} è
+possibile aprire le fifo anche in lettura/scrittura, operazione che avrà
+sempre successo immediato qualunque sia la modalità di apertura (bloccante e
+non bloccante); questo può essere utilizzato per aprire comunque una fifo in
+scrittura anche se non ci sono ancora processi il lettura; è possibile anche
+usare la fifo all'interno di un solo processo, nel qual caso però occorre
+stare molto attenti alla possibili deadlock.\footnote{se si cerca di leggere
+  da una fifo che non contiene dati si avrà un deadlock immediato, dato che il
+  processo si blocca e non potrà quindi mai eseguire le funzioni di
+  scrittura.}
+
+Per la loro caratteristica di essere accessibili attraverso il filesystem, è
+piuttosto frequente l'utilizzo di una fifo come canale di comunicazione nelle
+situazioni un processo deve ricevere informazioni dagli altri. In questo caso
+è fondamentale che le operazioni di scrittura siano atomiche; per questo si
+deve sempre tenere presente che questo è vero soltanto fintanto che non si
+supera il limite delle dimensioni di \macro{PIPE\_BUF} (si ricordi quanto
+detto in \secref{sec:ipc_pipes}).
+
+A parte il precedente, che resta probabilmente il più comune, Stevens riporta
+in \cite{APUE} altre due casistiche principali per l'uso delle fifo:
+\begin{itemize}
+\item Da parte dei comandi di shell, per evitare la creazione di file
+  temporanei quando si devono inviare i dati di uscita di un processo
+  sull'input di parecchi altri (attraverso l'uso del comando \cmd{tee}).
+  
+\item Come canale di comunicazione fra un client ed un server (il modello
+  \textit{client-server} è illustrato in \secref{sec:net_cliserv}).
+\end{itemize}
+
+Nel primo caso quello che si fa è creare tante pipe quanti sono i processi a
+cui i vogliono inviare i dati, da usare come standard input per gli stessi; una
+volta che li si saranno posti in esecuzione ridirigendo lo standard input si
+potrà eseguire il processo iniziale replicandone, con il comando \cmd{tee},
+l'output sulle pipe.
+
+Il secondo caso è relativamente semplice qualora si debba comunicare con un
+processo alla volta (nel qual caso basta usare due pipe, una per leggere ed
+una per scrivere), le cose diventano invece molto più complesse quando si
+vuole effettuare una comunicazione fra il server ed un numero imprecisato di
+client; se il primo infatti può ricevere le richieste attraverso una fifo
+``nota'', per le risposte non si può fare altrettanto, dato che, per la
+struttura sequenziale delle fifo, i client dovrebbero sapere, prima di
+leggerli, quando i dati inviati sono destinati a loro.
+
+Per risolvere questo problema, si può usare un'architettura come quella
+illustrata da Stevens in \cite{APUE}, in cui le risposte vengono inviate su
+fifo temporanee identificate dal \acr{pid} dei client, ma in ogni caso il
+sistema è macchinoso e continua ad avere vari inconvenienti\footnote{lo stesso
+  Stevens nota come sia impossibile per il server sapere se un client è andato
+  in crash, con la possibilità di far restare le fifo temporanee sul
+  filesystem, come sia necessario intercettare \macro{SIGPIPE} dato che un
+  client può terminare dopo aver fatto una richiesta, ma prima che la risposta
+  sia inviata, e come occorra gestire il caso in cui non ci sono client attivi
+  (e la lettura dalla fifo nota restituisca al serve un end-of-file.}; in
+generale infatti l'interfaccia delle fifo non è adatta a risolvere questo tipo
+di problemi, che possono essere affrontati in maniera più semplice ed efficace
+o usando i \textit{socket}\index{socket} (che tratteremo in dettaglio a
+partire da \capref{cha:socket_intro}) o ricorrendo a diversi meccanismi di
+comunicazione, come quelli che esamineremo in \secref{sec:ipc_sysv}.
 
-Utilizzando una fifo tutti i dati passeranno attraverso un apposito buffer nel
-kernel, senza transitare dal filesystem, l'inode serve solo a fornire un punto
-d'appoggio per i vari processi che permetta loro di accedere alla stessa
-fifo.  
 
 
+\section{La comunicazione fra processi di System V}
+\label{sec:ipc_sysv}
 
+Benché le pipe (e le fifo) siano ancora ampiamente usate, esse presentano
+numerosi limiti, il principale dei quali è che il meccanismo di comunicazione
+è rigidamente sequenziale; per questo una situazione in cui un processo scrive
+qualcosa che molti altri devono poter leggere non può essere implementata in
+maniera semplice con una pipe.
 
-Abbiamo già visto in \secref{sec:file_mknod} le modalità che permettono di
-creare una fifo, attraverso le funzioni \func{mknod} e \func{mkfifo}; per
-utilizzarle un processo non avrà che da aprire il relativo file in lettura o
-scrittura (a seconda della direzione che si vuole dare ai dati).
+Per superare questi limiti nello sviluppo di System V vennero introdotti una
+serie di nuovi oggetti di comunicazione e relative interfacce di
+programmazione in grado di garantire una maggiore flessibilità; in questa
+sezione esamineremo quello che viene ormai chiamato il \textsl{Sistema di
+  comunicazione inter-processo} di System V, (o \textit{System V IPC
+  (Inter-Process Comunication)}.
 
-che invece possono risiedere
-sul filesystem, e che i processi possono usare per le comunicazioni senza
-dovere per forza essere in relazione diretta.
 
 
+\subsection{Considerazioni generali}
+\label{sec:ipc_sysv_generic}
 
+La principale caratteristica del sistema di IPC di System V è quella di essere
+basato su oggetti permanenti che risiedono nel kernel. Questi, a differenza di
+quanto avviene per i file descriptor, non mantengono un contatore dei
+riferimenti, pertanto non vengono cancellati dal sistema una volta che non
+sono più in uso. Questo comporta che, al contrario di quanto avviene per pipe
+e fifo, la memoria allocata per questi oggetti non viene rilasciata
+automaticamente, ed essi devono essere cancellati esplicitamente, altrimenti
+resteranno attivi fintanto che non si riavvia il sistema. 
 
-Per poter superare il problema delle \textit{pipe}, illustrato in
-\secref{sec:ipc_pipes}, che ne consente l'uso solo fra processi con un
-progenitore comune o nella relazione padre/figlio,
-  
-\section{La comunicazione fra processi di System V}
-\label{sec:ipc_sysv}
+Gli oggetti usati nel System V IPC vengono creati direttamente dal kernel, e
+sono accessibili solo specificando il relativo \textsl{identificatore}, che è
+il numero progressivo che il kernel gli assengna quanto vengono creati (il
+prodedimento è simile a quello con cui si assegna il \acr{pid} dei processi).
+
+L'identificatore è in genere restituito dalle funzioni che creano l'oggetto,
+nasce quindi il problema di come processi diversi possono accedere allo stesso
+oggetto. Per far questo a ciascuno di essi viene anche associata una
+\textsl{chiave}, che può essere indicata in fasi di creazione. Usando la
+stessa chiave due processi diversi potranno ricavare l'identificatore
+associato ad un oggetto e accedervi entrambi.
+
+
+Questa caratteristica mostra il primo dei problemi associati al sistema di IPC
+di System V. Un secondo problema riguarda le modalità per l'accesso a questi
+oggetti. 
 
-Per ovviare ai vari limiti dei meccanismo tradizionale di comunicazione fra
-processi visto in \secref{sec:ipc_unix}, nello sviluppo di System V vennero
-introdotti una serie di nuovi oggetti e relative interfacce che garantissero
-una maggiore flessibilità; in questa sezione esamineremo quello che viene
-ormai chiamato il \textit{System V Inter-Process Comunication System}, più
-comunemente noto come \textit{SystemV IPC}.
 
 \subsection{Code di messaggi}
 \label{sec:ipc_messque}
 
-Il primo oggetto introdotto dal \textit{SystemV IPC} è quello delle code di
+Il primo oggetto introdotto dal \textit{System V IPC} è quello delle code di
 messaggi.
 
 \subsection{Semafori}
 \label{sec:ipc_semaph}
 
-Il secondo oggetto introdotto dal \textit{SystemV IPC} è quello dei semafori.
+Il secondo oggetto introdotto dal \textit{System V IPC} è quello dei semafori.
 
 
 \subsection{Memoria condivisa}
 \label{sec:ipc_shar_mem}
 
-Il terzo oggetto introdotto dal \textit{SystemV IPC} è quello della memoria
+Il terzo oggetto introdotto dal \textit{System V IPC} è quello della memoria
 condivisa.
 
+
+
+
+\section{La comunicazione fra processi di POSIX}
+\label{sec:ipc_posix}
+
+Lo standard POSIX.1b ha introdotto dei nuovi meccanismi di comunicazione,
+rifacendosi a quelli di System V, introducendo una nuova interfaccia che
+evitasse i principali problemi evidenziati in ...
+
+
+
+
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"