Sistemati gli indici.
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 3c30111cebf747b7316715bdcc672a4e373b441c..bdbdf2c13d9068e85617b49f2ff16cc321cf416e 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -101,6 +101,23 @@ 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 che ha aperto la 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}
 
 \subsection{Un esempio dell'uso delle pipe}
 \label{sec:ipc_pipe_use}
@@ -148,7 +165,7 @@ 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
 \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.
   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.
@@ -158,8 +175,8 @@ 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_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.
 
 
 nel file \file{BarCodePage.c} che si trova nella directory dei sorgenti.
 
 
@@ -219,7 +236,7 @@ int main(int argc, char *argv[], char *envp[])
   \normalsize 
   \caption{Sezione principale del codice del \textit{CGI} 
     \file{BarCodePage.c}.}
   \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
 \end{figure}
 
 La prima operazione del programma (\texttt{\small 4--12}) è quella di creare
@@ -227,10 +244,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
 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
 
 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 +302,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
 (\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.
 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 +349,7 @@ funzioni, \func{pclose}, il cui prototipo 
 \begin{prototype}{stdio.h}
 {int pclose(FILE *stream)}
 
 \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
 attendendo la terminazione del processo ad essa associato.
   
 \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
@@ -344,8 +361,8 @@ attendendo la terminazione del processo ad essa associato.
 \func{popen}.
 
 Per illustrare l'uso di queste due funzioni riprendiamo il problema
 \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
 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 +397,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
 
 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
 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
 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]
 invocato dopo.
 
 \begin{figure}[!htb]
@@ -427,12 +444,6 @@ int main(int argc, char *argv[], char *envp[])
         pclose((pipe[i]));
     }
     exit(0);
         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} 
 }
     \end{lstlisting}
   \end{minipage} 
@@ -472,61 +483,80 @@ 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
 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.
-
-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.  
-
-
-
-
-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).
-
-che invece possono risiedere
-sul filesystem, e che i processi possono usare per le comunicazioni senza
-dovere per forza essere in relazione diretta.
-
-
+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 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}
 
   
 \section{La comunicazione fra processi di System V}
 \label{sec:ipc_sysv}
 
-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}.
+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; una situazione in cui un processo scrive qualcosa
+che molti altri devono poter leggere non può essere implementata con una pipe.
+
+Per superarne i vari limiti, nello sviluppo di System V vennero introdotti una
+serie di nuovi oggetti di comunicazione e relative interfacce id
+programmazione che garantissero una maggiore flessibilità; in questa sezione
+esamineremo quello che viene ormai chiamato il \textsl{Sistema di
+  comunicazione inter-processo} di System V , più comunemente noto come
+\textit{System V IPC (Inter-Process Comunication)}.
  
 
 \subsection{Code di messaggi}
 \label{sec:ipc_messque}
 
  
 
 \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}
 
 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}
 
 
 
 \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.
 
 %%% Local Variables: 
 condivisa.
 
 %%% Local Variables: