Ancora reindicizzazioni, più CLONE_VFORK, CLONE_VM, CLONE_PTRACED
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index abe229a50538d4ffb8bd31449eba60c6f15f43a2..6f5f8cb2fbd9dea573cf42ca731b0ce0c1d63aa2 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -228,14 +228,14 @@ direzione del flusso dei dati è data dalle frecce continue.
 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} può essere eseguito più volte in contemporanea, e si avrebbe una
-evidente \itindex{race~condition} \textit{race condition} in caso di accesso
-simultaneo a detto file da istanze diverse. Il problema potrebbe essere
-superato utilizzando un sempre diverso per il file temporaneo, che verrebbe
-creato all'avvio di ogni istanza, utilizzato dai sottoprocessi, e cancellato
-alla fine della sua esecuzione; ma a questo punto le cose non sarebbero più
-tanto semplici.  L'uso di una \textit{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 \textit{race condition} in caso di accesso simultaneo a detto file da
+istanze diverse. Il problema potrebbe essere superato utilizzando un sempre
+diverso per il file temporaneo, che verrebbe creato all'avvio di ogni istanza,
+utilizzato dai sottoprocessi, e cancellato alla fine della sua esecuzione; ma
+a questo punto le cose non sarebbero più tanto semplici.  L'uso di una
+\textit{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
@@ -514,10 +514,10 @@ a quello illustrato per le \textit{pipe} in sez.~\ref{sec:ipc_pipes}.
 
 Abbiamo già trattato in sez.~\ref{sec:file_mknod} le funzioni \func{mknod} e
 \func{mkfifo} che permettono di creare una \textit{fifo}. Per utilizzarne una
-un processo non avrà che da aprire il relativo \index{file!speciali} file
-speciale o in lettura o scrittura; nel primo caso il processo sarà collegato
-al capo di uscita della \textit{fifo}, e dovrà leggere, nel secondo al capo di
-ingresso, e dovrà scrivere.
+un processo non avrà che da aprire il relativo file speciale o in lettura o
+scrittura; nel primo caso il processo sarà collegato al capo di uscita della
+\textit{fifo}, e dovrà leggere, nel secondo al capo di ingresso, e dovrà
+scrivere.
 
 Il kernel alloca un singolo buffer per ciascuna \textit{fifo} che sia stata
 aperta, e questa potrà essere acceduta contemporaneamente da più processi, sia
@@ -539,9 +539,8 @@ una \textit{fifo} in scrittura anche se non ci sono ancora processi il
 lettura. Infine è possibile anche usare la \textit{fifo} all'interno di un
 solo processo, nel qual caso però occorre stare molto attenti alla possibili
 situazioni di stallo: se si cerca di leggere da una \textit{fifo} che non
-contiene dati si avrà infatti un \itindex{deadlock} \textit{deadlock}
-immediato, dato che il processo si blocca e quindi non potrà mai eseguire le
-funzioni di scrittura.
+contiene dati si avrà infatti un \textit{deadlock} immediato, dato che il
+processo si blocca e quindi non potrà mai eseguire le funzioni di scrittura.
 
 Per la loro caratteristica di essere accessibili attraverso il filesystem, è
 piuttosto frequente l'utilizzo di una \textit{fifo} come canale di
@@ -739,7 +738,7 @@ scrittura e l'apertura si sarebbe bloccata indefinitamente.
 
 Verifichiamo allora il comportamento dei nostri programmi, in questo, come in
 altri esempi precedenti, si fa uso delle varie funzioni di servizio, che sono
-state raccolte nella libreria \file{libgapil.so}, per poter usare quest'ultima
+state raccolte nella libreria \file{libgapil.so}, e per poterla usare
 occorrerà definire la variabile di ambiente \envvar{LD\_LIBRARY\_PATH} in modo
 che il linker dinamico possa accedervi.
 
@@ -821,21 +820,21 @@ presenta il problema della unidirezionalità del flusso dei dati, è quello dei
 cosiddetti \textsl{socket locali} (o \textit{Unix domain socket}).  Tratteremo
 in generale i socket in cap.~\ref{cha:socket_intro}, nell'ambito
 dell'interfaccia che essi forniscono per la programmazione di rete, e vedremo
-anche (in~sez.~\ref{sec:sock_sa_local}) come si possono utilizzare i
-\index{file!speciali} file speciali di tipo socket, analoghi a quelli
-associati alle \textit{fifo} (si rammenti sez.~\ref{sec:file_file_types}) cui
-si accede però attraverso quella medesima interfaccia; vale però la pena
-esaminare qui una modalità di uso dei socket locali che li rende
-sostanzialmente identici ad una \textit{pipe} bidirezionale.
+anche (in~sez.~\ref{sec:sock_sa_local}) come si possono utilizzare i file
+speciali di tipo socket, analoghi a quelli associati alle \textit{fifo} (si
+rammenti sez.~\ref{sec:file_file_types}) cui si accede però attraverso quella
+medesima interfaccia; vale però la pena esaminare qui una modalità di uso dei
+socket locali che li rende sostanzialmente identici ad una \textit{pipe}
+bidirezionale.
 
 La funzione di sistema \funcd{socketpair}, introdotta da BSD ma supportata in
 genere da qualunque sistema che fornisca l'interfaccia dei socket ed inclusa
 in POSIX.1-2001, consente infatti di creare una coppia di file descriptor
 connessi fra loro (tramite un socket, appunto) senza dover ricorrere ad un
-\index{file!speciali} 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 è:
+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{funcproto}{
 \fhead{sys/types.h} 
@@ -865,11 +864,11 @@ 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 \val{0}.  
 
-A partire dal kernel 2.6.27 la funzione supporta anche l'uso dei flag
-\const{SOCK\_NONBLOCK} e \const{SOCK\_CLOEXEC} (trattati in
-sez.~\ref{sec:sock_type}) nell'indicazione del tipo di socket, con effetto
-identico agli analoghi \const{O\_CLOEXEC} e \const{O\_NONBLOCK} di una
-\func{open} (vedi tab.~\ref{tab:open_operation_flag}).
+A partire dal kernel 2.6.27 la funzione supporta nell'indicazione del tipo di
+socket anche i due flag \const{SOCK\_NONBLOCK} e \const{SOCK\_CLOEXEC}
+(trattati in sez.~\ref{sec:sock_type}), con effetto identico agli analoghi
+\const{O\_CLOEXEC} e \const{O\_NONBLOCK} di una \func{open} (vedi
+tab.~\ref{tab:open_operation_flag}).
 
 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
@@ -999,9 +998,8 @@ con i 16 bit meno significativi \itindex{inode} 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
-\itindex{minor~number} \textit{minor number}, come \file{/dev/hda1} e
-\file{/dev/sda1}.
+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
@@ -1314,22 +1312,26 @@ l'uso di \func{sysctl} o scrivendo nei file \sysctlrelfile{kernel}{msgmax},
 \sysctlrelfile{kernel}{msgmnb} e \sysctlrelfile{kernel}{msgmni} di
 \file{/proc/sys/kernel/}.
 
-Una coda di messaggi è costituita da una \itindex{linked~list} \textit{linked
-  list}.\footnote{una \itindex{linked~list} \textit{linked list} è una tipica
-  struttura di dati, organizzati in una lista in cui ciascun elemento contiene
-  un puntatore al successivo. In questo modo la struttura è veloce
-  nell'estrazione ed immissione dei dati dalle estremità dalla lista (basta
-  aggiungere un elemento in testa o in coda ed aggiornare un puntatore), e
-  relativamente veloce da attraversare in ordine sequenziale (seguendo i
-  puntatori), è invece relativamente lenta nell'accesso casuale e nella
-  ricerca.}  I nuovi messaggi vengono inseriti in coda alla lista e vengono
-letti dalla cima, in fig.~\ref{fig:ipc_mq_schema} si è riportato uno schema
-semplificato con cui queste strutture vengono mantenute dal kernel. Lo schema
-illustrato in realtà è una semplificazione di quello usato fino ai kernel
-della serie 2.2. A partire della serie 2.4 la gestione delle code di messaggi
-è effettuata in maniera diversa (e non esiste una struttura \struct{msqid\_ds}
-nel kernel), ma abbiamo mantenuto lo schema precedente dato che illustra in
-maniera più che adeguata i principi di funzionamento delle code di messaggi.
+\itindbeg{linked~list}
+
+Una coda di messaggi è costituita da una \textit{linked list}.\footnote{una
+  \itindex{linked~list} \textit{linked list} è una tipica struttura di dati,
+  organizzati in una lista in cui ciascun elemento contiene un puntatore al
+  successivo. In questo modo la struttura è veloce nell'estrazione ed
+  immissione dei dati dalle estremità dalla lista (basta aggiungere un
+  elemento in testa o in coda ed aggiornare un puntatore), e relativamente
+  veloce da attraversare in ordine sequenziale (seguendo i puntatori), è
+  invece relativamente lenta nell'accesso casuale e nella ricerca.}  I nuovi
+messaggi vengono inseriti in coda alla lista e vengono letti dalla cima, in
+fig.~\ref{fig:ipc_mq_schema} si è riportato uno schema semplificato con cui
+queste strutture vengono mantenute dal kernel. Lo schema illustrato in realtà
+è una semplificazione di quello usato fino ai kernel della serie 2.2. A
+partire della serie 2.4 la gestione delle code di messaggi è effettuata in
+maniera diversa (e non esiste una struttura \struct{msqid\_ds} nel kernel), ma
+abbiamo mantenuto lo schema precedente dato che illustra in maniera più che
+adeguata i principi di funzionamento delle code di messaggi.
+
+\itindend{linked~list}
 
 \begin{figure}[!htb]
   \centering \includegraphics[width=13cm]{img/mqstruct}
@@ -1844,14 +1846,13 @@ successivo potrebbe ricevere un messaggio non indirizzato a lui.
 I semafori non sono propriamente meccanismi di intercomunicazione come
 \textit{pipe}, \textit{fifo} e code di messaggi, poiché non consentono di
 scambiare dati fra processi, ma servono piuttosto come meccanismi di
-sincronizzazione o di protezione per le \index{sezione~critica}
-\textsl{sezioni critiche} del codice (si ricordi quanto detto in
-sez.~\ref{sec:proc_race_cond}).  Un semaforo infatti non è altro che un
-contatore mantenuto nel kernel che determina se consentire o meno la
-prosecuzione dell'esecuzione di un programma. In questo modo si può
-controllare l'accesso ad una risorsa condivisa da più processi, associandovi
-un semaforo che assicuri che non possa essere usata da più di un processo alla
-volta.
+sincronizzazione o di protezione per le \textsl{sezioni critiche} del codice
+(si ricordi quanto detto in sez.~\ref{sec:proc_race_cond}).  Un semaforo
+infatti non è altro che un contatore mantenuto nel kernel che determina se
+consentire o meno la prosecuzione dell'esecuzione di un programma. In questo
+modo si può controllare l'accesso ad una risorsa condivisa da più processi,
+associandovi un semaforo che assicuri che non possa essere usata da più di un
+processo alla volta.
 
 Il concetto di semaforo è uno dei concetti base nella programmazione ed è
 assolutamente generico, così come del tutto generali sono modalità con cui lo
@@ -2082,7 +2083,7 @@ specificata con \param{cmd}, ed opera o sull'intero insieme specificato da
     \includestruct{listati/semun.h}
   \end{minipage} 
   \normalsize 
-  \caption{La definizione dei possibili valori di una \direct{union}
+  \caption{La definizione dei possibili valori di una \dirct{union}
     \structd{semun}, usata come quarto argomento della funzione
     \func{semctl}.}
   \label{fig:ipc_semun}
@@ -2585,20 +2586,20 @@ di gestione del segmento di memoria condivisa in relazione al sistema della
 memoria virtuale.
 
 Il primo dei due flag è \const{SHM\_HUGETLB} che consente di richiedere la
-creazione del segmento usando una \itindex{huge~page} \textit{huge page}, le
-pagine di memoria di grandi dimensioni introdotte con il kernel 2.6 per
-ottimizzare le prestazioni nei sistemi più recenti che hanno grandi quantità
-di memoria. L'operazione è privilegiata e richiede che il processo abbia la
-\textit{capability} \const{CAP\_IPC\_LOCK}. Questa funzionalità è specifica di
-Linux e non è portabile.
+creazione del segmento usando una \textit{huge page}, le pagine di memoria di
+grandi dimensioni introdotte con il kernel 2.6 per ottimizzare le prestazioni
+nei sistemi più recenti che hanno grandi quantità di memoria. L'operazione è
+privilegiata e richiede che il processo abbia la \textit{capability}
+\const{CAP\_IPC\_LOCK}. Questa funzionalità è specifica di Linux e non è
+portabile.
 
 Il secondo flag aggiuntivo, introdotto a partire dal kernel 2.6.15, è
 \const{SHM\_NORESERVE}, ed ha lo stesso scopo del flag \const{MAP\_NORESERVE}
 di \func{mmap} (vedi sez.~\ref{sec:file_memory_map}): non vengono riservate
-delle pagine di swap ad uso del meccanismo del \textit{copy on write}
-\itindex{copy~on~write} per mantenere le modifiche fatte sul segmento. Questo
-significa che caso di scrittura sul segmento quando non c'è più memoria
-disponibile, si avrà l'emissione di un \signal{SIGSEGV}.
+delle pagine di swap ad uso del meccanismo del \textit{copy on write} per
+mantenere le modifiche fatte sul segmento. Questo significa che caso di
+scrittura sul segmento quando non c'è più memoria disponibile, si avrà
+l'emissione di un \signal{SIGSEGV}.
 
 Infine l'argomento \param{size} specifica la dimensione del segmento di
 memoria condivisa; il valore deve essere specificato in byte, ma verrà
@@ -2772,19 +2773,18 @@ consentono di estendere le funzionalità, ovviamente non devono essere usati se
 si ha a cuore la portabilità. Questi comandi aggiuntivi sono:
 
 \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
-\item[\const{SHM\_LOCK}] Abilita il \itindex{memory~locking} \textit{memory
-    locking} sul segmento di memoria condivisa, impedendo che la memoria usata
-  per il segmento venga salvata su disco dal meccanismo della memoria
-  virtuale. Come illustrato in sez.~\ref{sec:proc_mem_lock} fino al kernel
-  2.6.9 solo l'amministratore poteva utilizzare questa capacità,\footnote{che
-    richiedeva la \textit{capability} \const{CAP\_IPC\_LOCK}.} a partire dal
-  dal kernel 2.6.10 anche gli utenti normali possono farlo fino al limite
-  massimo determinato da \const{RLIMIT\_MEMLOCK} (vedi
+\item[\const{SHM\_LOCK}] Abilita il \textit{memory locking} sul segmento di
+  memoria condivisa, impedendo che la memoria usata per il segmento venga
+  salvata su disco dal meccanismo della memoria virtuale. Come illustrato in
+  sez.~\ref{sec:proc_mem_lock} fino al kernel 2.6.9 solo l'amministratore
+  poteva utilizzare questa capacità,\footnote{che richiedeva la
+    \textit{capability} \const{CAP\_IPC\_LOCK}.} a partire dal dal kernel
+  2.6.10 anche gli utenti normali possono farlo fino al limite massimo
+  determinato da \const{RLIMIT\_MEMLOCK} (vedi
   sez.~\ref{sec:sys_resource_limit}).
-\item[\const{SHM\_UNLOCK}] Disabilita il \itindex{memory~locking}
-  \textit{memory locking} sul segmento di memoria condivisa.  Fino al kernel
-  2.6.9 solo l'amministratore poteva utilizzare questo comando in
-  corrispondenza di un segmento da lui bloccato. 
+\item[\const{SHM\_UNLOCK}] Disabilita il \textit{memory locking} sul segmento
+  di memoria condivisa.  Fino al kernel 2.6.9 solo l'amministratore poteva
+  utilizzare questo comando in corrispondenza di un segmento da lui bloccato.
 \end{basedescript}
 
 A questi due, come per \func{msgctl} e \func{semctl}, si aggiungono tre
@@ -2815,7 +2815,7 @@ il suo prototipo è:
 }
 
 {La funzione ritorna l'indirizzo del segmento in caso di successo e $-1$ (in
-  un cast a \type{void *}) per un errore, nel qual caso \var{errno} assumerà
+  un cast a \ctyp{void *}) per un errore, nel qual caso \var{errno} assumerà
   uno dei valori:
   \begin{errlist}
     \item[\errcode{EACCES}] il processo non ha i privilegi per accedere al
@@ -2880,12 +2880,12 @@ indirizzo come arrotondamento.
 
 L'uso di \const{SHM\_RDONLY} permette di agganciare il segmento in sola
 lettura (si ricordi che anche le pagine di memoria hanno dei permessi), in tal
-caso un tentativo di scrivere sul segmento comporterà una
-\itindex{segment~violation} violazione di accesso con l'emissione di un
-segnale di \signal{SIGSEGV}. Il comportamento usuale di \func{shmat} è quello
-di agganciare il segmento con l'accesso in lettura e scrittura (ed il processo
-deve aver questi permessi in \var{shm\_perm}), non è prevista la possibilità
-di agganciare un segmento in sola scrittura.
+caso un tentativo di scrivere sul segmento comporterà una violazione di
+accesso con l'emissione di un segnale di \signal{SIGSEGV}. Il comportamento
+usuale di \func{shmat} è quello di agganciare il segmento con l'accesso in
+lettura e scrittura (ed il processo deve aver questi permessi in
+\var{shm\_perm}), non è prevista la possibilità di agganciare un segmento in
+sola scrittura.
 
 Infine \const{SHM\_REMAP} è una estensione specifica di Linux (quindi non
 portabile) che indica che la mappatura del segmento deve rimpiazzare ogni
@@ -3034,10 +3034,10 @@ ricavare la parte di informazione che interessa.
 
 In fig.~\ref{fig:ipc_dirmonitor_main} si è riportata la sezione principale del
 corpo del programma server, insieme alle definizioni delle altre funzioni
-usate nel programma e delle \index{variabili!globali} variabili globali,
-omettendo tutto quello che riguarda la gestione delle opzioni e la stampa
-delle istruzioni di uso a video; al solito il codice completo si trova con i
-sorgenti allegati nel file \file{DirMonitor.c}.
+usate nel programma e delle variabili globali, omettendo tutto quello che
+riguarda la gestione delle opzioni e la stampa delle istruzioni di uso a
+video; al solito il codice completo si trova con i sorgenti allegati nel file
+\file{DirMonitor.c}.
 
 \begin{figure}[!htbp]
   \footnotesize \centering
@@ -3049,11 +3049,11 @@ sorgenti allegati nel file \file{DirMonitor.c}.
   \label{fig:ipc_dirmonitor_main}
 \end{figure}
 
-Il programma usa delle \index{variabili!globali} variabili globali
-(\texttt{\small 2-14}) per mantenere i valori relativi agli oggetti usati per
-la comunicazione inter-processo; si è definita inoltre una apposita struttura
-\struct{DirProp} che contiene i dati relativi alle proprietà che si vogliono
-mantenere nella memoria condivisa, per l'accesso da parte dei client.
+Il programma usa delle variabili globali (\texttt{\small 2-14}) per mantenere
+i valori relativi agli oggetti usati per la comunicazione inter-processo; si è
+definita inoltre una apposita struttura \struct{DirProp} che contiene i dati
+relativi alle proprietà che si vogliono mantenere nella memoria condivisa, per
+l'accesso da parte dei client.
 
 Il programma, dopo la sezione, omessa, relativa alla gestione delle opzioni da
 riga di comando (che si limitano alla eventuale stampa di un messaggio di
@@ -3066,12 +3066,11 @@ con un messaggio di errore.
 Poi, per verificare che l'argomento specifichi effettivamente una directory,
 si esegue (\texttt{\small 24-26}) su di esso una \func{chdir}, uscendo
 immediatamente in caso di errore.  Questa funzione serve anche per impostare
-la \index{directory~di~lavoro} directory di lavoro del programma nella
-directory da tenere sotto controllo, in vista del successivo uso della
-funzione \func{daemon}. Si noti come si è potuta fare questa scelta,
-nonostante le indicazioni illustrate in sez.~\ref{sec:sess_daemon}, per il
-particolare scopo del programma, che necessita comunque di restare all'interno
-di una directory.
+la directory di lavoro del programma nella directory da tenere sotto
+controllo, in vista del successivo uso della funzione \func{daemon}. Si noti
+come si è potuta fare questa scelta, nonostante le indicazioni illustrate in
+sez.~\ref{sec:sess_daemon}, per il particolare scopo del programma, che
+necessita comunque di restare all'interno di una directory.
 
 Infine (\texttt{\small 27-29}) si installano i gestori per i vari segnali di
 terminazione che, avendo a che fare con un programma che deve essere eseguito
@@ -3100,9 +3099,9 @@ intercomunicazione il programma entra nel ciclo principale (\texttt{\small
 Il primo passo (\texttt{\small 41}) è eseguire \func{daemon} per proseguire
 con l'esecuzione in background come si conviene ad un programma demone; si
 noti che si è mantenuta, usando un valore non nullo del primo argomento, la
-\index{directory~di~lavoro} directory di lavoro corrente.  Una volta che il
-programma è andato in background l'esecuzione prosegue all'interno di un ciclo
-infinito (\texttt{\small 42-48}).
+directory di lavoro corrente.  Una volta che il programma è andato in
+background l'esecuzione prosegue all'interno di un ciclo infinito
+(\texttt{\small 42-48}).
 
 Si inizia (\texttt{\small 43}) bloccando il mutex con \func{MutexLock} per
 poter accedere alla memoria condivisa (la funzione si bloccherà
@@ -3132,11 +3131,11 @@ esse la funzione \func{ComputeValues}, che esegue tutti i calcoli necessari.
 
 
 Il codice di quest'ultima è riportato in fig.~\ref{fig:ipc_dirmonitor_sub}.
-Come si vede la funzione (\texttt{\small 2-16}) è molto semplice e si limita
-chiamare (\texttt{\small 5}) la funzione \func{stat} sul file indicato da
+Come si vede la funzione (\texttt{\small 2-16}) è molto semplice e si limita a
+chiamare (\texttt{\small 5}) la funzione \func{stat} sul file indicato da
 ciascuna voce, per ottenerne i dati, che poi utilizza per incrementare i vari
-contatori nella memoria condivisa, cui accede grazie alla
-\index{variabili!globali} variabile globale \var{shmptr}.
+contatori nella memoria condivisa, cui accede grazie alla variabile globale
+\var{shmptr}.
 
 Dato che la funzione è chiamata da \myfunc{dir\_scan}, si è all'interno del
 ciclo principale del programma, con un mutex acquisito, perciò non è
@@ -3326,7 +3325,7 @@ relativamente poco diffuso.
 \subsection{I \textsl{file di lock}}
 \label{sec:ipc_file_lock}
 
-\index{file!di lock|(}
+\index{file!di~lock|(}
 
 Come illustrato in sez.~\ref{sec:ipc_sysv_sem} i semafori del \textit{SysV-IPC}
 presentano una interfaccia inutilmente complessa e con alcuni difetti
@@ -3344,12 +3343,12 @@ directory, \file{/var/lock}, nella standardizzazione del \textit{Filesystem
 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 è comunque soggetti alla
-  possibilità di una \itindex{race~condition} \textit{race condition}.} che
-essa ritorni un errore quando usata con i flag di \const{O\_CREAT} e
-\const{O\_EXCL}. In tal modo la creazione di un \textsl{file di lock} può
-essere eseguita atomicamente, il processo che crea il file con successo si può
-considerare come titolare del lock (e della risorsa ad esso associata) mentre
-il rilascio si può eseguire con una chiamata ad \func{unlink}.
+  possibilità di una \textit{race condition}.} che essa ritorni un errore
+quando usata con i flag di \const{O\_CREAT} e \const{O\_EXCL}. In tal modo la
+creazione di un \textsl{file di lock} può essere eseguita atomicamente, il
+processo che crea il file con successo si può considerare come titolare del
+lock (e della risorsa ad esso associata) mentre il rilascio si può eseguire
+con una chiamata ad \func{unlink}.
 
 Un esempio dell'uso di questa funzione è mostrato dalle funzioni
 \func{LockFile} ed \func{UnlockFile} riportate in fig.~\ref{fig:ipc_file_lock}
@@ -3399,23 +3398,23 @@ 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.
 
-\index{file!di lock|)}
+\index{file!di~lock|)}
 
 
 \subsection{La sincronizzazione con il \textit{file locking}}
 \label{sec:ipc_lock_file}
 
-Dato che i \index{file!di lock} file di lock presentano gli inconvenienti
-illustrati in precedenza, la tecnica alternativa di sincronizzazione più
-comune è quella di fare ricorso al \itindex{file~locking} \textit{file
-  locking} (trattato in sez.~\ref{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 \itindex{polling} \textit{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.
+Dato che i file di lock presentano gli inconvenienti illustrati in precedenza,
+la tecnica alternativa di sincronizzazione più comune è quella di fare ricorso
+al \itindex{file~locking} \textit{file locking} (trattato in
+sez.~\ref{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 \itindex{polling} \textit{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
@@ -4148,12 +4147,12 @@ che se si vuole mantenere il meccanismo di notifica occorre ripetere la
 registrazione chiamando nuovamente \func{mq\_notify} all'interno del gestore
 del segnale di notifica. A differenza della situazione simile che si aveva con
 i segnali non affidabili (l'argomento è stato affrontato in
-\ref{sec:sig_semantics}) questa caratteristica non configura una
-\itindex{race~condition} \textit{race condition} perché l'invio di un segnale
-avviene solo se la coda è vuota; pertanto se si vuole evitare di correre il
-rischio di perdere eventuali ulteriori segnali inviati nel lasso di tempo che
-occorre per ripetere la richiesta di notifica basta avere cura di eseguire
-questa operazione prima di estrarre i messaggi presenti dalla coda.
+\ref{sec:sig_semantics}) questa caratteristica non configura una \textit{race
+  condition} perché l'invio di un segnale avviene solo se la coda è vuota;
+pertanto se si vuole evitare di correre il rischio di perdere eventuali
+ulteriori segnali inviati nel lasso di tempo che occorre per ripetere la
+richiesta di notifica basta avere cura di eseguire questa operazione prima di
+estrarre i messaggi presenti dalla coda.
 
 L'invio del segnale di notifica avvalora alcuni campi di informazione
 restituiti al gestore attraverso la struttura \struct{siginfo\_t} (definita in
@@ -4627,8 +4626,8 @@ dall'argomento \param{sem}, se questo era nullo la relativa risorsa risulterà
 sbloccata, cosicché un altro processo (o \itindex{thread} \textit{thread})
 eventualmente bloccato in una \func{sem\_wait} sul semaforo possa essere
 svegliato e rimesso in esecuzione.  Si tenga presente che la funzione è sicura
-\index{funzioni!sicure} per l'uso all'interno di un gestore di segnali (si
-ricordi quanto detto in sez.~\ref{sec:sig_signal_handler}).
+per l'uso all'interno di un gestore di segnali (si ricordi quanto detto in
+sez.~\ref{sec:sig_signal_handler}).
 
 Se invece di operare su un semaforo se ne volesse semplicemente leggere il
 valore, si potrà usare la funzione \funcd{sem\_getvalue}, il cui prototipo è:
@@ -4762,12 +4761,11 @@ il semaforo deve essere utilizzato dai \itindex{thread} \textit{thread} di uno
 stesso processo (con un valore nullo) o condiviso fra processi diversi (con un
 valore non nullo).
 
-Qualora il semaforo debba essere condiviso dai \itindex{thread}
-\textit{thread} di uno stesso processo (nel qual caso si parla di
-\textit{thread-shared semaphore}), occorrerà che \param{sem} sia l'indirizzo
-di una variabile visibile da tutti i \itindex{thread} \textit{thread}, si
-dovrà usare cioè una \index{variabili!globali} variabile globale o una
-variabile allocata dinamicamente nello \itindex{heap} \textit{heap}.
+Qualora il semaforo debba essere condiviso dai \textit{thread} di uno stesso
+processo (nel qual caso si parla di \textit{thread-shared semaphore}),
+occorrerà che \param{sem} sia l'indirizzo di una variabile visibile da tutti i
+\textit{thread}, si dovrà usare cioè una variabile globale o una variabile
+allocata dinamicamente nello \textit{heap}.
 
 Qualora il semaforo debba essere condiviso fra più processi (nel qual caso si
 parla di \textit{process-shared semaphore}) la sola scelta possibile per
@@ -4848,9 +4846,9 @@ dall'altro programma prima di averla finita di stampare.
 
 La parte iniziale del programma contiene le definizioni (\texttt{\small 1-8})
 del gestore del segnale usato per liberare le risorse utilizzate, delle
-\index{variabili!globali} variabili globali contenenti i nomi di default del
-segmento di memoria condivisa e del semaforo (il default scelto è
-\texttt{messages}), e delle altre variabili utilizzate dal programma.
+variabili globali contenenti i nomi di default del segmento di memoria
+condivisa e del semaforo (il default scelto è \texttt{messages}), e delle
+altre variabili utilizzate dal programma.
 
 Come prima istruzione (\texttt{\small 10}) si è provveduto ad installare un
 gestore di segnale che consentirà di effettuare le operazioni di pulizia
@@ -4879,12 +4877,12 @@ notazione ottale). Infine il semaforo verrà inizializzato ad un valore nullo
 A questo punto (\texttt{\small 22}) si potrà inizializzare il messaggio posto
 nel segmento di memoria condivisa usando la stringa passata come argomento al
 programma. Essendo il semaforo stato creato già bloccato non ci si dovrà
-preoccupare di eventuali \itindex{race~condition} \textit{race condition}
-qualora il programma di modifica del messaggio venisse lanciato proprio in
-questo momento.  Una volta inizializzato il messaggio occorrerà però
-rilasciare il semaforo (\texttt{\small 24-27}) per consentirne l'uso; in
-tutte queste operazioni si provvederà ad uscire dal programma con un opportuno
-messaggio in caso di errore.
+preoccupare di eventuali \textit{race condition} qualora il programma di
+modifica del messaggio venisse lanciato proprio in questo momento.  Una volta
+inizializzato il messaggio occorrerà però rilasciare il semaforo
+(\texttt{\small 24-27}) per consentirne l'uso; in tutte queste operazioni si
+provvederà ad uscire dal programma con un opportuno messaggio in caso di
+errore.
 
 Una volta completate le inizializzazioni il ciclo principale del programma
 (\texttt{\small 29-47}) viene ripetuto indefinitamente (\texttt{\small 29})
@@ -4955,8 +4953,8 @@ argomento.
 Una volta completate con successo le precedenti inizializzazioni, il passo
 seguente (\texttt{\small 21-24}) è quello di acquisire il semaforo, dopo di
 che sarà possibile eseguire la sostituzione del messaggio (\texttt{\small 25})
-senza incorrere in possibili \itindex{race~condition} \textit{race condition}
-con la stampa dello stesso da parte di \file{message\_getter}.
+senza incorrere in possibili \textit{race condition} con la stampa dello
+stesso da parte di \file{message\_getter}.
 
 Una volta effettuata la modifica viene stampato (\texttt{\small 26}) il tempo
 di attesa impostato con l'opzione ``\texttt{-t}'' dopo di che (\texttt{\small
@@ -5013,10 +5011,10 @@ message: ciao
 \end{Console}
 %$
 
-E si noterà come nel momento in cui si è lanciato \file{message\_setter} le
-stampe di \file{message\_getter} si bloccheranno, come corretto, dopo aver
-registrato un valore nullo per il semaforo.  Il programma infatti resterà
-bloccato nella \func{sem\_wait} (quella di riga (\texttt{\small 37}) in
+E si noterà come nel momento in cui si lancia \file{message\_setter} le stampe
+di \file{message\_getter} si bloccheranno, come corretto, dopo aver registrato
+un valore nullo per il semaforo.  Il programma infatti resterà bloccato nella
+\func{sem\_wait} (quella di riga (\texttt{\small 37}) in
 fig.~\ref{fig:ipc_posix_sem_shm_message_server}) fino alla scadenza
 dell'attesa di \file{message\_setter} (con l'esecuzione della \func{sem\_post}
 della riga (\texttt{\small 29}) di