Inizio delle considerazioni sull'uso della shared memory.
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 0aac002739cfe6037360890146c6f76b1aa4dadc..47210133d3db4c92b29cd38486e3f5425e7b6792 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 è:
@@ -360,7 +360,7 @@ 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
-  errore; nel quel caso il valore di \func{errno} deriva dalle sottostanti
+  errore; nel quel caso il valore di \var{errno} deriva dalle sottostanti
   chiamate.}
 \end{prototype}
 \noindent che oltre alla chiusura dello stream si incarica anche di attendere
@@ -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
@@ -1229,8 +1231,12 @@ mantenuta staticamente all'interno del sistema.
 
 Il primo oggetto introdotto dal \textit{SysV IPC} è quello delle code di
 messaggi.  Le code di messaggi sono oggetti analoghi alle pipe o alle fifo,
-anche se la loro struttura è diversa. La funzione che permette di ottenerne
-una è \func{msgget} ed il suo prototipo è:
+anche se la loro struttura è diversa, ed il loro scopo principale è appunto
+quello di permettere a processi diversi di scambiarsi dei dati.
+
+La funzione che permette di richiedere al sistema l'identificatore di una coda
+di messaggi esistente (o di crearne una se questa non esiste) è \func{msgget};
+il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
@@ -1271,7 +1277,7 @@ Se invece si specifica un valore diverso da \const{IPC\_PRIVATE}\footnote{in
 dipende dal valore di \param{flag}, se questo è nullo la funzione si limita ad
 effettuare una ricerca sugli oggetti esistenti, restituendo l'identificatore
 se trova una corrispondenza, o fallendo con un errore di \errcode{ENOENT} se
-non esiste o di \errcode{EACCESS} se si sono specificati dei permessi non
+non esiste o di \errcode{EACCES} se si sono specificati dei permessi non
 validi.
 
 Se invece si vuole creare una nuova coda di messaggi \param{flag} non può
@@ -1867,10 +1873,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.
 
 
 
@@ -2562,22 +2568,7 @@ il mutex. Entrambe fanno da wrapper per \func{semop}, utilizzando le due
 strutture \var{sem\_lock} e \var{sem\_unlock} definite in precedenza
 (\texttt{\small 32--42}). Si noti come per queste ultime si sia fatto uso
 dell'opzione \const{SEM\_UNDO} per evitare che il semaforo resti bloccato in
-caso di terminazione imprevista del processo.%%  Si noti infine come, essendo
-%% tutte le funzioni riportate in \figref{fig:ipc_mutex_create} estremamente
-%% semplici, se si sono definite tutte come \ctyp{inline}.\footnote{la direttiva
-%%   \func{inline} viene usata per dire al compilatore di non trattare la
-%%   funzione cui essa fa riferimento come una funzione, ma di inserire il codice
-%%   direttamente nel testo del programma.  Anche se i compilatori più moderni
-%%   sono in grado di effettuare da soli queste manipolazioni (impostando le
-%%   opportune ottimizzazioni) questa è una tecnica usata per migliorare le
-%%   prestazioni per le funzioni piccole ed usate di frequente, in tal caso
-%%   infatti le istruzioni per creare un nuovo frame nello stack per chiamare la
-%%   funzione costituirebbero una parte rilevante del codice, appesantendo
-%%   inutilmente il programma. Originariamente questa era fatto utilizzando delle
-%%   macro, ma queste hanno tutta una serie di problemi di sintassi nel passaggio
-%%   degli argomenti (si veda ad esempio \cite{PratC} che in questo modo possono
-%%   essere evitati.}
-
+caso di terminazione imprevista del processo.
 
 Chiamare \func{MutexLock} decrementa il valore del semaforo: se questo è
 libero (ha già valore 1) sarà bloccato (valore nullo), se è bloccato la
@@ -2591,7 +2582,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}.
 
 
 
@@ -2932,6 +2923,38 @@ In caso di successo la funzione aggiorna anche i seguenti campi di
 inoltre la regione di indirizzi usata per il segmento di memoria condivisa
 viene tolta dallo spazio di indirizzi del processo.
 
+Benché la memoria condivisa costituisca il meccanismo di intercomunicazione
+fra processi più veloce, essa non è sempre il più appropriato, dato che, come
+abbiamo visto, si avrà comunque la necessità di una sincronizzazione degli
+accessi.  Per questo motivo, quando la comunicazione fra processi è
+sequenziale, altri meccanismi come le pipe, le fifo o i socket, che non
+necessitano di sincronizzazione esplicita, sono da preferire. Essa diventa
+l'unico meccanismo possibile quando la comunicazione non è
+sequenziale\footnote{come accennato in \secref{sec:ipc_sysv_mq} per la
+  comunicazione non sequenziale si possono usare le code di messaggi,
+  attraverso l'uso del campo \var{mtype}, ma solo se quest'ultima può essere
+  effettuata in forma di messaggio.} o quando non può avvenire secondo una
+modalità predefinita.
+
+Un esempio classico di uso della memoria condivisa è quello del ``monitor'',
+in cui essa viene per scambiare informazioni fra un processo ``server'' che vi
+scrive dei dati di interesse generale che ha ottenuto, e tutti i processi
+``client'' interessati agli stessi dati che così possono leggerli in maniera
+completamente asincrona.  Con questo schema di funzionamento da una parte si
+evita che ciascun processo ``client'' debbia compiere l'operazione,
+potenzialmente onerosa, di ricavare e trattare i dati, e dall'altra si evita
+al processo ``server'' di dover gestire l'invio a tutti i client di tutti i
+dati (non potendo il server sapere quali di essi servono effettivamente al
+singolo client).
+
+Nel nostro caso implementeremo un ``monitor'' di una directory: un processo si
+incaricherà di tenere sotto controllo alcuni parametri relativi ad una
+directory (il numero dei file contenuti, la dimenzione totale, ecc.) che
+saranno salvati in un segmento di memoria condivisa cui altri processi
+potranno accedere per ricavare la parte di informazione che interessa.
+
+
+
 
 %% Per capire meglio il funzionamento delle funzioni facciamo ancora una volta
 %% riferimento alle strutture con cui il kernel implementa i segmenti di memoria
@@ -2953,9 +2976,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.
 
@@ -2966,23 +2989,25 @@ tecniche alternative, che vogliamo riprendere in questa sezione.
 Le code di messaggi sono probabilmente il meno usato degli oggetti del
 \textit{SysV IPC}; esse infatti nacquero principalmente come meccanismo di
 comunicazione bidirezionale quando ancora le pipe erano unidirezionali; con la
-disponibilità di \func{socketpair} (vedi \secref{sec:ipc_socketpair}) si può
-ottenere lo stesso risultato senza incorrere nelle complicazioni introdotte
-dal \textit{SysV IPC}.
+disponibilità di \func{socketpair} (vedi \secref{sec:ipc_socketpair}) o
+utilizzando una coppia di pipe, si può ottenere questo risultato senza
+incorrere nelle complicazioni introdotte 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 è
+relativamente 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 +3017,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 +3074,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 +3084,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 +3094,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 +3171,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 +3227,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 
 
 
@@ -3229,13 +3256,15 @@ superiorit
 \subsection{Code di messaggi}
 \label{sec:ipc_posix_mq}
 
-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. 
+Le code di messaggi non sono ancora supportate nel kernel
+ufficiale;\footnote{esiste però una proposta di implementazione di Krzysztof
+  Benedyczak, a partire dal kernel 2.5.50.}  inoltre esse possono essere
+implementate, usando la memoria condivisa ed i mutex, con funzioni di
+libreria. In generale, come le corrispettive del SysV IPC, sono poco usate,
+dato che i socket\index{socket}, nei casi in cui sono sufficienti, sono più
+comodi, e negli altri casi la comunicazione può essere gestita direttamente
+con mutex e memoria condivisa. Per questo ci limiteremo ad una descrizione
+essenziale.
 
 
 
@@ -3244,7 +3273,9 @@ descrizione essenziale.
 
 Dei semafori POSIX esistono sostanzialmente due implementazioni; una è fatta a
 livello di libreria ed è fornita dalla libreria dei thread; questa però li
-implementa solo a livello di thread e non di processi. Esiste una 
+implementa solo a livello di thread e non di processi. Esiste un'altra
+versione, realizzata da Konstantin Knizhnik, che reimplementa l'interfaccia
+POSIX usando i semafori di SysV IPC. 
 
 
 \subsection{Memoria condivisa}