Rifinitura degli indici, correzioni ortografiche varie.
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 2848182..da8d317 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -169,13 +169,13 @@ direzione del flusso dei dati 
 Si potrebbe obiettare che sarebbe molto più semplice salvare il risultato
 intermedio su un file temporaneo. Questo però non tiene conto del fatto che un
 \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 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, oltre ad essere
-molto più efficiente, dato che non si deve scrivere su disco.
+evidente race condition\index{race condition} in caso di accesso simultaneo a
+detto file.\footnote{il problema potrebbe essere superato determinando in
+  anticipo 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, 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
@@ -348,8 +348,8 @@ programma indicato) in caso si sia indicato \code{"r"}, o in sola scrittura (e
 quindi associato allo standard input) in caso di \code{"w"}.
 
 Lo stream restituito da \func{popen} è identico a tutti gli effetti ai file
-stream visti in \secref{cha:files_std_interface}, anche se è collegato ad una
-pipe e non ad un inode, e viene sempre aperto in modalità
+stream visti in \capref{cha:files_std_interface}, anche se è collegato ad una
+pipe e non ad un inode\index{inode}, e viene sempre aperto in modalità
 \textit{fully-buffered} (vedi \secref{sec:file_buffering}); l'unica differenza
 con gli usuali stream è che dovrà essere chiuso dalla seconda delle due nuove
 funzioni, \func{pclose}, il cui prototipo è:
@@ -493,15 +493,16 @@ 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 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}.
+attraverso un inode\index{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}.
+l'inode\index{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
@@ -528,8 +529,8 @@ 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 situazioni di
 stallo.\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.}
+  avrà un deadlock\index{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
@@ -823,10 +824,10 @@ come quelli che esamineremo in seguito.
 Un meccanismo di comunicazione molto simile alle pipe, ma che non presenta il
 problema della unidirezionalità del flusso dei dati, è quello dei cosiddetti
 \textsl{socket locali} (o \textit{Unix domain socket}). Tratteremo l'argomento
-dei \textit{socket} in \capref{cha:socket_intro},\footnote{si tratta comunque
-  di oggetti di comunicazione che, come le pipe, sono utilizzati attraverso
-  dei file descriptor.} nell'ambito dell'interfaccia generale che essi
-forniscono per la programmazione di rete; e vedremo anche
+dei \textit{socket}\index{socket} in \capref{cha:socket_intro},\footnote{si
+  tratta comunque di oggetti di comunicazione che, come le pipe, sono
+  utilizzati attraverso dei file descriptor.} nell'ambito dell'interfaccia
+generale che essi forniscono per la programmazione di rete; e vedremo anche
 (in~\secref{sec:sock_sa_local}) come si possono definire dei file speciali (di
 tipo \textit{socket}, analoghi a quello associati alle fifo) cui si accede
 però attraverso quella medesima interfaccia; vale però la pena esaminare qui
@@ -836,26 +837,27 @@ una modalit
 identici ad una pipe bidirezionale.
 
 La funzione \func{socketpair} infatti consente di creare una coppia di file
-descriptor connessi fra di loro (tramite un socket, appunto), senza dover
-ricorrere ad un file speciale sul filesystem, i descrittori sono del tutto
-analoghi a quelli che si avrebbero con una chiamata a \func{pipe}, con la sola
-differenza è che in questo caso il flusso dei dati può essere effettuato in
-entrambe le direzioni. Il prototipo della funzione è:
+descriptor connessi fra di loro (tramite un socket\index{socket}, appunto),
+senza dover ricorrere ad un file speciale sul filesystem, i descrittori sono
+del tutto analoghi a quelli che si avrebbero con una chiamata a \func{pipe},
+con la sola differenza è che in questo caso il flusso dei dati può essere
+effettuato in entrambe le direzioni. Il prototipo della funzione è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/socket.h} 
   
   \funcdecl{int socketpair(int domain, int type, int protocol, int sv[2])}
   
-  Crea una coppia di socket connessi fra loro.
+  Crea una coppia di socket\index{socket} connessi fra loro.
   
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
     errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EAFNOSUPPORT}] I socket locali non sono supportati.
+  \item[\errcode{EAFNOSUPPORT}] I socket\index{socket} locali non sono
+    supportati.
   \item[\errcode{EPROTONOSUPPORT}] Il protocollo specificato non è supportato.
   \item[\errcode{EOPNOTSUPP}] Il protocollo specificato non supporta la
-  creazione di coppie di socket.
+  creazione di coppie di socket\index{socket}.
   \end{errlist}
   ed inoltre \errval{EMFILE},  \errval{EFAULT}.
 }
@@ -864,18 +866,18 @@ entrambe le direzioni. Il prototipo della funzione 
 La funzione restituisce in \param{sv} la coppia di descrittori connessi fra di
 loro: quello che si scrive su uno di essi sarà ripresentato in input
 sull'altro e viceversa. I parametri \param{domain}, \param{type} e
-\param{protocol} derivano dall'interfaccia dei socket (che è quella che
-fornisce il substrato per connettere i due descrittori), ma in questo caso i
-soli valori validi che possono essere specificati sono rispettivamente
-\const{AF\_UNIX}, \const{SOCK\_STREAM} e \var{0}.
+\param{protocol} derivano dall'interfaccia dei socket\index{socket} (che è
+quella che fornisce il substrato per connettere i due descrittori), ma in
+questo caso i soli valori validi che possono essere specificati sono
+rispettivamente \const{AF\_UNIX}, \const{SOCK\_STREAM} e \var{0}.
 
 L'utilità di chiamare questa funzione per evitare due chiamate a \func{pipe}
-può sembrare limitata; in realtà l'utilizzo di questa funzione (e dei socket
-locali in generale) permette di trasmettere attraverso le linea non solo dei
-dati, ma anche dei file descriptor: si può cioè passare da un processo ad un
-altro un file descriptor, con una sorta di duplicazione dello stesso non
-all'interno di uno stesso processo, ma fra processi distinti (torneremo su
-questa funzionalità in \secref{sec:xxx_fd_passing}). 
+può sembrare limitata; in realtà l'utilizzo di questa funzione (e dei
+socket\index{socket} locali in generale) permette di trasmettere attraverso le
+linea non solo dei dati, ma anche dei file descriptor: si può cioè passare da
+un processo ad un altro un file descriptor, con una sorta di duplicazione
+dello stesso non all'interno di uno stesso processo, ma fra processi distinti
+(torneremo su questa funzionalità in \secref{sec:xxx_fd_passing}).
 
 
 \section{La comunicazione fra processi di System V}
@@ -1001,12 +1003,12 @@ significativi.\footnote{nelle libc4 e libc5, come avviene in SunOS,
 
 Il problema è che anche così non c'è la sicurezza che il valore della chiave
 sia univoco, infatti esso è costruito combinando il byte di \param{proj\_id)}
-con i 16 bit meno significativi dell'inode del file \param{pathname} (che
-vengono ottenuti attraverso \func{stat}, da cui derivano i possibili errori),
-e gli 8 bit meno significativi del numero del dispositivo su cui è il file.
-Diventa perciò relativamente facile ottenere delle collisioni, specie se i
-file sono su dispositivi con lo stesso \textit{minor number}, come
-\file{/dev/hda1} e \file{/dev/sda1}.
+con i 16 bit meno significativi dell'inode\index{inode} del file
+\param{pathname} (che vengono ottenuti attraverso \func{stat}, da cui derivano
+i possibili errori), e gli 8 bit meno significativi del numero del dispositivo
+su cui è il file.  Diventa perciò relativamente facile ottenere delle
+collisioni, specie se i file sono su dispositivi con lo stesso \textit{minor
+  number}, come \file{/dev/hda1} e \file{/dev/sda1}.
 
 In genere quello che si fa è utilizzare un file comune usato dai programmi che
 devono comunicare (ad esempio un header comune, o uno dei programmi che devono
@@ -1867,10 +1869,10 @@ viene interrotto dopo l'invio del messaggio di richiesta e prima della lettura
 della risposta, quest'ultima resta nella coda (così come per le fifo si aveva
 il problema delle fifo che restavano nel filesystem). In questo caso però il
 problemi sono maggiori, sia perché è molto più facile esaurire la memoria
-dedicata ad una coda di messaggi che gli inode di un filesystem, sia perché,
-con il riutilizzo dei \acr{pid} da parte dei processi, un client eseguito in
-un momento successivo potrebbe ricevere un messaggio non indirizzato a
-lui.
+dedicata ad una coda di messaggi che gli inode\index{inode} di un filesystem,
+sia perché, con il riutilizzo dei \acr{pid} da parte dei processi, un client
+eseguito in un momento successivo potrebbe ricevere un messaggio non
+indirizzato a lui.
 
 
 
@@ -2591,7 +2593,7 @@ crescerebbe oltre 1, e \func{MutexLock} non avrebbe pi
 che usare \func{MutexRead} per controllare il valore dei mutex prima di
 proseguire non servirebbe comunque, dato che l'operazione non sarebbe atomica.
 Vedremo in \secref{sec:ipc_posix_sem} come è possibile ottenere un'interfaccia
-analoga senza questo problemi usando il file locking.
+analoga senza questo problemi usando il file locking\index{file!locking}.
 
 
 
@@ -2953,9 +2955,9 @@ viene tolta dallo spazio di indirizzi del processo.
 \label{sec:ipc_alternatives}
 
 Come abbiamo detto in \secref{sec:ipc_sysv_generic}, e ripreso nella
-descrizione dei signoli oggetti che ne fan parte, il \textit{SysV IPC}
+descrizione dei singoli oggetti che ne fan parte, il \textit{SysV IPC}
 presenta numerosi problemi; in \cite{APUE}\footnote{in particolare nel
-  capitolo 14.}  Stevens ne eeffettua una accurata analisi (alcuni dei
+  capitolo 14.}  Stevens ne effettua una accurata analisi (alcuni dei
 concetti sono già stati accennati in precedenza) ed elenca alcune possibili
 tecniche alternative, che vogliamo riprendere in questa sezione.
 
@@ -2973,16 +2975,18 @@ dal \textit{SysV IPC}.
 In realtà, grazie alla presenza del campo \var{mtype}, le code di messaggi
 hanno delle caratteristiche ulteriori, consentendo una classificazione dei
 messaggi ed un accesso non rigidamente sequenziale; due caratteristiche che
-sono impossibili da ottenere con le pipe e i socket di \func{socketpair}.  A
-queste esigenze però si può comunque ovviare in maniera diversa con un uso
-combinato della memoria condivisa e dei meccanismi di sincronizzazione, per
-cui alla fine l'uso delle code di messaggi classiche è poco diffuso.
+sono impossibili da ottenere con le pipe e i socket\index{socket} di
+\func{socketpair}.  A queste esigenze però si può comunque ovviare in maniera
+diversa con un uso combinato della memoria condivisa e dei meccanismi di
+sincronizzazione, per cui alla fine l'uso delle code di messaggi classiche è
+poco diffuso.
 
 
 
 \subsection{I \textsl{file di lock}}
 \label{sec:ipc_file_lock}
 
+\index{file!di lock|(}
 Come illustrato in \secref{sec:ipc_sysv_sem} i semafori del \textit{SysV IPC}
 presentano una interfaccia inutilmente complessa e con alcuni difetti
 strutturali, per questo quando si ha una semplice esigenza di sincronizzazione
@@ -2992,9 +2996,9 @@ necessit
 alternativi.
 
 La prima possibilità, utilizzata fin dalle origini di Unix, è quella di usare
-dei \textsl{file di lock}\index{file di lock} (per i quali esiste anche una
-opportuna directory, \file{/var/lock}, nel filesystem standard). Per questo si
-usa la caratteristica della funzione \func{open} (illustrata in
+dei \textsl{file di lock} (per i quali esiste anche una opportuna directory,
+\file{/var/lock}, nel filesystem standard). Per questo si usa la
+caratteristica della funzione \func{open} (illustrata in
 \secref{sec:file_open}) che prevede\footnote{questo è quanto dettato dallo
   standard POSIX.1, ciò non toglie che in alcune implementazioni questa
   tecnica possa non funzionare; in particolare per Linux, nel caso di NFS, si
@@ -3049,8 +3053,8 @@ Uno dei limiti di questa tecnica 
 (la funzione viene eseguita, ma non è garantita l'atomicità dell'operazione)
 se il filesystem su cui si va ad operare è su NFS; in tal caso si può adottare
 una tecnica alternativa che prevede l'uso della \func{link} per creare come
-file di lock un hard link ad un file esistente; se il link esiste già e la
-funzione fallisce, significa che la risorsa è bloccata e potrà essere
+\textsl{file di lock} un hard link ad un file esistente; se il link esiste già
+e la funzione fallisce, significa che la risorsa è bloccata e potrà essere
 sbloccata solo con un \func{unlink}, altrimenti il link è creato ed il lock
 acquisito; il controllo e l'eventuale acquisizione sono atomici; la soluzione
 funziona anche su NFS, ma ha un'altro difetto è che è quello di poterla usare
@@ -3059,9 +3063,9 @@ solo se si opera all'interno di uno stesso filesystem.
 Un generale comunque l'uso di un \textsl{file di lock} presenta parecchi
 problemi, che non lo rendono una alternativa praticabile per la
 sincronizzazione: anzitutto anche in questo caso, in caso di terminazione
-imprevista del processo, si lascia allocata la risorsa (il file di lock) e
-questa deve essere sempre cancellata esplicitamente.  Inoltre il controllo
-della disponibilità può essere eseguito solo con una tecnica di
+imprevista del processo, si lascia allocata la risorsa (il \textsl{file di
+  lock}) e questa deve essere sempre cancellata esplicitamente.  Inoltre il
+controllo della disponibilità può essere eseguito solo con una tecnica di
 \textit{polling}\index{polling}, ed è quindi molto inefficiente.
 
 La tecnica dei file di lock non di meno ha una sua utilità, e può essere usata
@@ -3069,21 +3073,23 @@ con successo quando l'esigenza 
 risorsa, senza necessità di attendere che questa si liberi; ad esempio la si
 usa spesso per evitare interferenze sull'uso delle porte seriali da parte di
 più programmi: qualora si trovi un file di lock il programma che cerca di
-accedere alla seriale si limita a segnalare che la risorsa non è disponibile.
+accedere alla seriale si limita a segnalare che la risorsa non è
+disponibile.\index{file!di lock|)}
 
 \subsection{La sincronizzazione con il \textit{file locking}}
 \label{sec:ipc_lock_file}
 
 Dato che i file di lock presentano gli inconvenienti illustrati in precedenza,
 la tecnica alternativa più comune è quella di fare ricorso al \textit{file
-  locking} (trattato in \secref{sec:file_locking}) usando \func{fcntl} su un
-file creato per l'occasione per ottenere un write lock. In questo modo potremo
-usare il lock come un \textit{mutex}: per bloccare la risorsa basterà
-acquisire il lock, per sbloccarla basterà rilasciare il lock; una richiesta
-fatta con un write lock metterà automaticamente il processo in stato di
-attesa, senza necessità di ricorrere al \textit{polling}\index{polling} per
-determinare la disponibilità della risorsa, e al rilascio della stessa da
-parte del processo che la occupava si otterrà il nuovo lock atomicamente.
+  locking}\index{file!locking} (trattato in \secref{sec:file_locking}) usando
+\func{fcntl} su un file creato per l'occasione per ottenere un write lock. In
+questo modo potremo usare il lock come un \textit{mutex}: per bloccare la
+risorsa basterà acquisire il lock, per sbloccarla basterà rilasciare il lock;
+una richiesta fatta con un write lock metterà automaticamente il processo in
+stato di attesa, senza necessità di ricorrere al
+\textit{polling}\index{polling} per determinare la disponibilità della
+risorsa, e al rilascio della stessa da parte del processo che la occupava si
+otterrà il nuovo lock atomicamente.
 
 Questo approccio presenta il notevole vantaggio che alla terminazione di un
 processo tutti i lock acquisiti vengono rilasciati automaticamente (alla
@@ -3144,15 +3150,15 @@ int UnlockMutex(const char *path_name)
   \end{minipage} 
   \normalsize 
   \caption{Il codice delle funzioni che permettono di creare un
-    \textit{mutex} utilizzando il file locking.}
+    \textit{mutex} utilizzando il file locking\index{file!locking}.}
   \label{fig:ipc_flock_mutex}
 \end{figure}
 
-Il codice per implementare un mutex utilizzando il file locking è riportato in
-\figref{fig:ipc_flock_mutex}; a differenza del precedente caso in cui si sono
-usati i semafori le funzioni questa volta sono sufficienti due funzioni,
-\func{LockMutex} e \func{UnlockMutex}, usate rispettivamente per acquisire e
-rilasciare il mutex.
+Il codice per implementare un mutex utilizzando il file
+locking\index{file!locking} è riportato in \figref{fig:ipc_flock_mutex}; a
+differenza del precedente caso in cui si sono usati i semafori le funzioni
+questa volta sono sufficienti due funzioni, \func{LockMutex} e
+\func{UnlockMutex}, usate rispettivamente per acquisire e rilasciare il mutex.
 
 La prima funzione (\texttt{\small 1--22}) serve per acquisire il mutex.
 Anzitutto si apre (\texttt{\small 9--11}), creandolo se non esiste, il file
@@ -3200,7 +3206,7 @@ il \textit{memory mapping} anonimo.\footnote{nei sistemi derivati da SysV una
   \file{/dev/zero}. In tal caso i valori scritti nella regione mappata non
   vengono ignorati (come accade qualora si scriva direttamente sul file), ma
   restano in memoria e possono essere riletti secondo le stesse modalità usate
-  nele \textit{memory mapping} anonimo.} Un esempio di utilizzo di questa
+  nel \textit{memory mapping} anonimo.} Un esempio di utilizzo di questa
 tecnica è mostrato in 
 
 
@@ -3231,11 +3237,11 @@ superiorit
 
 Le code di messaggi non sono supportate a livello del kernel, esse però
 possono essere implementate, usando la memoria condivisa ed i mutex, con
-funzioni di libreria. In generale esse sono comunque poco usate, i socket, nei
-casi in cui sono sufficienti, sono più comodi, e negli altri casi la
-comunicazione può essere gestita direttamente con la stessa metodologia usata
-per implementare le code di messaggi. Per questo ci limiteremo ad una
-descrizione essenziale. 
+funzioni di libreria. In generale esse sono comunque poco usate, i
+socket\index{socket}, nei casi in cui sono sufficienti, sono più comodi, e
+negli altri casi la comunicazione può essere gestita direttamente con la
+stessa metodologia usata per implementare le code di messaggi. Per questo ci
+limiteremo ad una descrizione essenziale.