Iniziato a rivedere il multiplexing I/O.
[gapil.git] / fileadv.tex
index 2d3ce015b9acb4563d1d9b350f3fbec4937b1dd7..4415602bcce799513de037ee02f7867f09dfc093 100644 (file)
@@ -1,6 +1,6 @@
 %% fileadv.tex
 %%
 %% fileadv.tex
 %%
-%% Copyright (C) 2000-2002 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2003 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Prefazione",
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Prefazione",
@@ -70,15 +70,15 @@ I/O non bloccante.
 \label{sec:file_multiplexing}
 
 Per superare il problema di dover usare il \textit{polling}\index{polling} per
 \label{sec:file_multiplexing}
 
 Per superare il problema di dover usare il \textit{polling}\index{polling} per
-controllare la possibilità di effettuare operazioni su un file aperto in
-modalità non bloccante, sia BSD che System V hanno introdotto delle nuove
-funzioni in grado di sospendere l'esecuzione di un processo in attesa che
-l'accesso diventi possibile.  Il primo ad introdurre questa modalità di
-operazione, chiamata usualmente \textit{I/O multiplexing}, è stato
-BSD,\footnote{la funzione è apparsa in BSD4.2 e standardizzata in BSD4.4, ma è
-  stata portata su tutti i sistemi che supportano i
-  \textit{socket}\index{socket}, compreso le varianti di System V.}  con la
-funzione \funcd{select}, il cui prototipo è:
+controllare la possibilità di effettuare operazioni su un gruppo di file
+aperti in modalità non bloccante, sia BSD che System V hanno introdotto delle
+nuove funzioni in grado di sospendere l'esecuzione di un processo fin quando
+l'accesso ad un dato insieme di file diventi possibile.  Il primo ad
+introdurre questa modalità di operazione, chiamata usualmente \textit{I/O
+  multiplexing}, è stato BSD,\footnote{la funzione è apparsa in BSD4.2 e
+  standardizzata in BSD4.4, ma è stata portata su tutti i sistemi che
+  supportano i \textit{socket}\index{socket}, compreso le varianti di System
+  V.}  con la funzione \funcd{select}, il cui prototipo è:
 \begin{functions}
   \headdecl{sys/time.h}
   \headdecl{sys/types.h}
 \begin{functions}
   \headdecl{sys/time.h}
   \headdecl{sys/types.h}
@@ -135,10 +135,14 @@ opportune macro di preprocessore:
 In genere un \textit{file descriptor set} può contenere fino ad un massimo di
 \const{FD\_SETSIZE} file descriptor.  Questo valore in origine corrispondeva
 al limite per il numero massimo di file aperti\footnote{ad esempio in Linux,
 In genere un \textit{file descriptor set} può contenere fino ad un massimo di
 \const{FD\_SETSIZE} file descriptor.  Questo valore in origine corrispondeva
 al limite per il numero massimo di file aperti\footnote{ad esempio in Linux,
-  fino alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma
+  fino alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma da
 quando, come nelle versioni più recenti del kernel, non c'è più un limite
 massimo, esso indica le dimensioni massime dei numeri usati nei \textit{file
 quando, come nelle versioni più recenti del kernel, non c'è più un limite
 massimo, esso indica le dimensioni massime dei numeri usati nei \textit{file
-  descriptor set}.
+  descriptor set}.\footnote{il suo valore, secondo lo standard POSIX
+  1003.1-2001, è definito in \file{sys/select.h}, ed è pari a 1024.} Si tenga
+presente che i \textit{file descriptor set} devono sempre essere inizializzati
+con \macro{FD\_ZERO}; passare a \func{select} un valore non inizializzato può
+dar luogo a comportamenti non prevedibili.
 
 La funzione richiede di specificare tre insiemi distinti di file descriptor;
 il primo, \param{readfds}, verrà osservato per rilevare la disponibilità di
 
 La funzione richiede di specificare tre insiemi distinti di file descriptor;
 il primo, \param{readfds}, verrà osservato per rilevare la disponibilità di
@@ -147,17 +151,24 @@ possibilit
 verificare l'esistenza di condizioni eccezionali (come i messaggi urgenti su
 un \textit{socket}\index{socket}, vedi \secref{sec:xxx_urgent}).
 
 verificare l'esistenza di condizioni eccezionali (come i messaggi urgenti su
 un \textit{socket}\index{socket}, vedi \secref{sec:xxx_urgent}).
 
-La funzione inoltre richiede anche di specificare, tramite l'argomento
-\param{n}, un valore massimo del numero dei file descriptor usati
-nell'insieme; si può usare il già citato \const{FD\_SETSIZE}, oppure il numero
-più alto dei file descriptor usati nei tre insiemi, aumentato di uno.
+Dato che in genere non si tengono mai sotto controllo fino a
+\const{FD\_SETSIZE} file contemporaneamente la funzione richiede di
+specificare qual'è il numero massimo dei file descriptor indicati nei tre
+insiemi precedenti. Questo viene fatto per efficienza, per evitare di passare
+e far controllare al kernel una quantità di memoria superiore a quella
+necessaria. Questo limite viene indicato tramite l'argomento \param{n}, che
+deve corrispondere al valore massimo aumentato di uno.\footnote{i file
+  descriptor infatti sono contati a partire da zero, ed il valore indica il
+  numero di quelli da tenere sotto controllo; dimenticarsi di aumentare di uno
+  il valore di \param{n} è un errore comune.}
 
 Infine l'argomento \param{timeout}, specifica un tempo massimo di
 
 Infine l'argomento \param{timeout}, specifica un tempo massimo di
-attesa\footnote{il tempo è valutato come \textit{elapsed time}.} prima che la
-funzione ritorni; se impostato a \val{NULL} la funzione attende
-indefinitamente. Si può specificare anche un tempo nullo (cioè una struttura
-\struct{timeval} con i campi impostati a zero), qualora si voglia
-semplicemente controllare lo stato corrente dei file descriptor.
+attesa\footnote{il tempo è valutato come \textit{clock time} (vedi
+  \secref{sec:sys_unix_time}).} prima che la funzione ritorni; se impostato a
+\val{NULL} la funzione attende indefinitamente. Si può specificare anche un
+tempo nullo (cioè una struttura \struct{timeval} con i campi impostati a
+zero), qualora si voglia semplicemente controllare lo stato corrente dei file
+descriptor.
 
 La funzione restituisce il totale dei file descriptor pronti nei tre insiemi,
 il valore zero indica sempre che si è raggiunto un timeout. Ciascuno dei tre
 
 La funzione restituisce il totale dei file descriptor pronti nei tre insiemi,
 il valore zero indica sempre che si è raggiunto un timeout. Ciascuno dei tre
@@ -167,35 +178,35 @@ operazioni ad esso relative, in modo da poterlo controllare con la macro
 non vengono toccati.
 
 In Linux \func{select} modifica anche il valore di \param{timeout},
 non vengono toccati.
 
 In Linux \func{select} modifica anche il valore di \param{timeout},
-impostandolo al tempo restante; questo è utile quando la funzione viene
-interrotta da un segnale, in tal caso infatti si ha un errore di
-\errcode{EINTR}, ed occorre rilanciare la funzione; in questo modo non è
-necessario ricalcolare tutte le volte il tempo rimanente.\footnote{questo può
-  causare problemi di portabilità sia quando si trasporta codice scritto su
-  Linux che legge questo valore, sia quando si usano programmi scritti per
-  altri sistemi che non dispongono di questa caratteristica e ricalcolano
-  \param{timeout} tutte le volte. In genere la caratteristica è disponibile
-  nei sistemi che derivano da System V e non disponibile per quelli che
-  derivano da BSD.}
-
-Come accennato l'interfaccia di \func{select} è una estensione di BSD; anche
-System V ha introdotto una sua interfaccia per gestire l'\textit{I/O
-  multiplexing}, basata sulla funzione \funcd{poll},\footnote{la funzione è
-  prevista dallo standard XPG4, ed è stata introdotta in Linux come system
-  call a partire dal kernel 2.1.23 e dalle \acr{libc} 5.4.28.} il cui
+impostandolo al tempo restante in caso di interruzione prematura; questo è
+utile quando la funzione viene interrotta da un segnale, in tal caso infatti
+si ha un errore di \errcode{EINTR}, ed occorre rilanciare la funzione; in
+questo modo non è necessario ricalcolare tutte le volte il tempo
+rimanente.\footnote{questo può causare problemi di portabilità sia quando si
+  trasporta codice scritto su Linux che legge questo valore, sia quando si
+  usano programmi scritti per altri sistemi che non dispongono di questa
+  caratteristica e ricalcolano \param{timeout} tutte le volte. In genere la
+  caratteristica è disponibile nei sistemi che derivano da System V e non
+  disponibile per quelli che derivano da BSD.}
+
+Come accennato l'interfaccia di \func{select} è una estensione creata nello
+sviluppo di BSD; anche System V ha introdotto una sua interfaccia per gestire
+l'\textit{I/O multiplexing}, basata sulla funzione \funcd{poll},\footnote{la
+  funzione è prevista dallo standard XPG4, ed è stata introdotta in Linux come
+  system call a partire dal kernel 2.1.23 e dalle \acr{libc} 5.4.28.} il cui
 prototipo è:
 \begin{prototype}{sys/poll.h}
   {int poll(struct pollfd *ufds, unsigned int nfds, int timeout)}
 prototipo è:
 \begin{prototype}{sys/poll.h}
   {int poll(struct pollfd *ufds, unsigned int nfds, int timeout)}
-
-La funzione attente un cambiamento di stato per uno dei file descriptor
-specificati da \param{ufds}.
+  
+  La funzione attende un cambiamento di stato per uno dei file descriptor
+  specificati da \param{ufds}.
   
 \bodydesc{La funzione restituisce il numero di file descriptor con attività in
   caso di successo, o 0 se c'è stato un timeout; in caso di errore viene
   restituito  -1 ed \var{errno} assumerà uno dei valori:
   \begin{errlist}
   \item[\errcode{EBADF}] Si è specificato un file descriptor sbagliato in uno
   
 \bodydesc{La funzione restituisce il numero di file descriptor con attività in
   caso di successo, o 0 se c'è stato un timeout; in caso di errore viene
   restituito  -1 ed \var{errno} assumerà uno dei valori:
   \begin{errlist}
   \item[\errcode{EBADF}] Si è specificato un file descriptor sbagliato in uno
-  degli insiemi.
+    degli insiemi.
   \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
   \end{errlist}
   ed inoltre \errval{EFAULT} e \errval{ENOMEM}.}
   \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
   \end{errlist}
   ed inoltre \errval{EFAULT} e \errval{ENOMEM}.}
@@ -211,17 +222,11 @@ negativo indica un'attesa indefinita).
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct pollfd {
-        int fd;           /* file descriptor */
-        short events;     /* requested events */
-        short revents;    /* returned events */
-};
-    \end{lstlisting}
+    \includestruct{listati/pollfd.h}
   \end{minipage} 
   \normalsize 
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \struct{pollfd}, utilizzata per specificare le modalità
-    di controllo di un file descriptor alla funzione \func{poll}.}
+  \caption{La struttura \structd{pollfd}, utilizzata per specificare le
+    modalità di controllo di un file descriptor alla funzione \func{poll}.}
   \label{fig:file_pollfd}
 \end{figure}
 
   \label{fig:file_pollfd}
 \end{figure}
 
@@ -254,7 +259,8 @@ vengono utilizzati solo per \var{revents} come valori in uscita).
     \const{POLLWRNORM}& 0x100 & È possibile la scrittura di dati normali.  \\ 
     \const{POLLWRBAND}& 0x200 & È possibile la scrittura di dati ad 
                                 alta priorità. \\
     \const{POLLWRNORM}& 0x100 & È possibile la scrittura di dati normali.  \\ 
     \const{POLLWRBAND}& 0x200 & È possibile la scrittura di dati ad 
                                 alta priorità. \\
-    \const{POLLMSG}   & 0x400 & Estensione propria di Linux.\\
+    \const{POLLMSG}   & 0x400 & Un segnale \const{SIGPOLL} è arrivato alla
+                                cima dello stream.\\
     \hline    
   \end{tabular}
   \caption{Costanti per l'identificazione dei vari bit dei campi
     \hline    
   \end{tabular}
   \caption{Costanti per l'identificazione dei vari bit dei campi
@@ -313,12 +319,22 @@ della funzione.
 L'uso di \param{sigmask} è stato introdotto allo scopo di prevenire possibili
 race condition\footnote{in Linux però, non esistendo una system call apposita,
   la funzione è implementata nelle \acr{glibc} usando \func{select}, e la
 L'uso di \param{sigmask} è stato introdotto allo scopo di prevenire possibili
 race condition\footnote{in Linux però, non esistendo una system call apposita,
   la funzione è implementata nelle \acr{glibc} usando \func{select}, e la
-  possibilità di una race condition resta.} quando si deve eseguire un test su
-una variabile assegnata da un manipolatore sulla base dell'occorrenza di un
-segnale per decidere se lanciare \func{select}. Fra il test e l'esecuzione è
-presente una finestra in cui potrebbe arrivare il segnale che non sarebbe
-rilevato; la race condition diventa superabile disabilitando il segnale prima
-del test e riabilitandolo poi grazie all'uso di \param{sigmask}.
+  possibilità di una race condition\index{race condition} resta.} quando si
+deve eseguire un test su una variabile assegnata da un gestore sulla base
+dell'occorrenza di un segnale per decidere se lanciare \func{select}. Fra il
+test e l'esecuzione è presente una finestra in cui potrebbe arrivare il
+segnale che non sarebbe rilevato; la race condition\index{race condition}
+diventa superabile disabilitando il segnale prima del test e riabilitandolo
+poi grazie all'uso di \param{sigmask}.
+
+Dato che l'I/O multiplexing serve a risolvere il problema di dover attendere
+la disponibilità di accesso ad un insieme di file, esso viene utilizzato
+prevalentemente per programmi in cui l'accesso ad un file descriptor può
+essere bloccante. Abbiamo già accennato come questo non avvenga mai per i
+normali file su disco; l'uso più comune di queste funzioni infatti è nei
+server di rete, in cui esse vengono utilizzate per tenere sotto controllo vari
+socket; pertanto ritorneremo su di esse con maggiori dettagli e con qualche
+esempio in \secref{sec:TCP_sock_multiplexing}.
 
 
 
 
 
 
@@ -362,14 +378,14 @@ pi
 Linux però supporta le estensioni POSIX.1b dei segnali che permettono di
 superare il problema facendo ricorso alle informazioni aggiuntive restituite
 attraverso la struttura \struct{siginfo\_t}, utilizzando la forma estesa
 Linux però supporta le estensioni POSIX.1b dei segnali che permettono di
 superare il problema facendo ricorso alle informazioni aggiuntive restituite
 attraverso la struttura \struct{siginfo\_t}, utilizzando la forma estesa
-\var{sa\_sigaction} del manipolatore (si riveda quanto illustrato in
+\var{sa\_sigaction} del gestore (si riveda quanto illustrato in
 \secref{sec:sig_sigaction}).
 
 Per far questo però occorre utilizzare le funzionalità dei segnali real-time
 (vedi \secref{sec:sig_real_time}) impostando esplicitamente con il comando
 \const{F\_SETSIG} di \func{fcntl} un segnale real-time da inviare in caso di
 I/O asincrono (il segnale predefinito è \const{SIGIO}). In questo caso il
 \secref{sec:sig_sigaction}).
 
 Per far questo però occorre utilizzare le funzionalità dei segnali real-time
 (vedi \secref{sec:sig_real_time}) impostando esplicitamente con il comando
 \const{F\_SETSIG} di \func{fcntl} un segnale real-time da inviare in caso di
 I/O asincrono (il segnale predefinito è \const{SIGIO}). In questo caso il
-manipolatore tutte le volte che riceverà \const{SI\_SIGIO} come valore del
+gestore tutte le volte che riceverà \const{SI\_SIGIO} come valore del
 campo \var{si\_code}\footnote{il valore resta \const{SI\_SIGIO} qualunque sia
   il segnale che si è associato all'I/O asincrono, ed indica appunto che il
   segnale è stato generato a causa di attività nell'I/O asincrono.} di
 campo \var{si\_code}\footnote{il valore resta \const{SI\_SIGIO} qualunque sia
   il segnale che si è associato all'I/O asincrono, ed indica appunto che il
   segnale è stato generato a causa di attività nell'I/O asincrono.} di
@@ -404,9 +420,10 @@ di thread. Al momento\footnote{fino ai kernel della serie 2.4.x, nella serie
   di I/O, che prevede anche l'introduzione di un nuovo layer per l'I/O
   asincrono (effettuato a partire dal 2.5.32).} esiste una sola versione
 stabile di questa interfaccia, quella delle \acr{glibc}, che è realizzata
   di I/O, che prevede anche l'introduzione di un nuovo layer per l'I/O
   asincrono (effettuato a partire dal 2.5.32).} esiste una sola versione
 stabile di questa interfaccia, quella delle \acr{glibc}, che è realizzata
-completamente in user space.  Esistono comunque vari progetti sperimentali
-(come il KAIO della SGI, o i patch di Benjamin La Haise) che prevedono un
-supporto diretto da parte del kernel.
+completamente in user space, ed accessibile linkando i programmi con la
+libreria \file{librt}.  Esistono comunque vari progetti sperimentali (come il
+KAIO della SGI, o i patch di Benjamin La Haise) che prevedono un supporto
+diretto da parte del kernel.
 
 Lo standard prevede che tutte le operazioni di I/O asincrono siano controllate
 attraverso l'uso di una apposita struttura \struct{aiocb} (il cui nome sta per
 
 Lo standard prevede che tutte le operazioni di I/O asincrono siano controllate
 attraverso l'uso di una apposita struttura \struct{aiocb} (il cui nome sta per
@@ -419,21 +436,10 @@ disponibilit
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct aiocb
-{
-    int aio_fildes;               /* File descriptor.  */
-    off_t aio_offset;             /* File offset */
-    int aio_lio_opcode;           /* Operation to be performed.  */
-    int aio_reqprio;              /* Request priority offset.  */
-    volatile void *aio_buf;       /* Location of buffer.  */
-    size_t aio_nbytes;            /* Length of transfer.  */
-    struct sigevent aio_sigevent; /* Signal number and value.  */
-};
-    \end{lstlisting}
+    \includestruct{listati/aiocb.h}
   \end{minipage} 
   \normalsize 
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \struct{aiocb}, usata per il controllo dell'I/O
+  \caption{La struttura \structd{aiocb}, usata per il controllo dell'I/O
     asincrono.}
   \label{fig:file_aiocb}
 \end{figure}
     asincrono.}
   \label{fig:file_aiocb}
 \end{figure}
@@ -469,20 +475,11 @@ esse.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct sigevent
-{
-    sigval_t sigev_value;
-    int sigev_signo;
-    int sigev_notify;
-    sigev_notify_function;
-    sigev_notify_attributes;
-};
-    \end{lstlisting}
+    \includestruct{listati/sigevent.h}
   \end{minipage} 
   \normalsize 
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \struct{sigevent}, usata per specificare le modalità di
-    notifica degli eventi relativi alle operazioni di I/O asincrono.}
+  \caption{La struttura \structd{sigevent}, usata per specificare le modalità
+    di notifica degli eventi relativi alle operazioni di I/O asincrono.}
   \label{fig:file_sigevent}
 \end{figure}
 
   \label{fig:file_sigevent}
 \end{figure}
 
@@ -492,15 +489,17 @@ notifica del completamento delle operazioni richieste. La struttura 
 riportata in \secref{fig:file_sigevent}; il campo \var{sigev\_notify} è quello
 che indica le modalità della notifica, esso può assumere i tre valori:
 \begin{basedescript}{\desclabelwidth{3.0cm}}
 riportata in \secref{fig:file_sigevent}; il campo \var{sigev\_notify} è quello
 che indica le modalità della notifica, esso può assumere i tre valori:
 \begin{basedescript}{\desclabelwidth{3.0cm}}
-\item[\const{SIGEV\_NONE}]   Non viene inviata nessuna notifica.
+\item[\const{SIGEV\_NONE}]  Non viene inviata nessuna notifica.
 \item[\const{SIGEV\_SIGNAL}] La notifica viene effettuata inviando al processo
 \item[\const{SIGEV\_SIGNAL}] La notifica viene effettuata inviando al processo
-  chiamante il segnale specificato nel campo \var{sigev\_signo}, se il
-  manipolatore è installato con \const{SA\_SIGINFO}, il gli verrà restituito
-  il valore di \var{sigev\_value} in come valore del campo \var{si\_value} per
+  chiamante il segnale specificato da \var{sigev\_signo}; se il gestore di
+  questo è stato installato con \const{SA\_SIGINFO} gli verrà restituito il
+  valore di \var{sigev\_value} (la cui definizione è in
+  \figref{fig:sig_sigval}) come valore del campo \var{si\_value} di
   \struct{siginfo\_t}.
 \item[\const{SIGEV\_THREAD}] La notifica viene effettuata creando un nuovo
   \struct{siginfo\_t}.
 \item[\const{SIGEV\_THREAD}] La notifica viene effettuata creando un nuovo
-  thread che esegue la funzione specificata da \var{sigev\_notify\_function},
-  con gli attributi specificati da \var{sigev\_notify\_attribute}.
+  thread che esegue la funzione specificata da \var{sigev\_notify\_function}
+  con argomento \var{sigev\_value}, e con gli attributi specificati da
+  \var{sigev\_notify\_attribute}.
 \end{basedescript}
 
 Le due funzioni base dell'interfaccia per l'I/O asincrono sono
 \end{basedescript}
 
 Le due funzioni base dell'interfaccia per l'I/O asincrono sono
@@ -814,15 +813,10 @@ il secondo, \var{iov\_len}, la dimensione dello stesso.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct iovec {
-    __ptr_t iov_base;    /* Starting address */
-    size_t iov_len;      /* Length in bytes  */
-};
-    \end{lstlisting}
+    \includestruct{listati/iovec.h}
   \end{minipage} 
   \normalsize 
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \struct{iovec}, usata dalle operazioni di I/O
+  \caption{La struttura \structd{iovec}, usata dalle operazioni di I/O
     vettorizzato.} 
   \label{fig:file_iovec}
 \end{figure}
     vettorizzato.} 
   \label{fig:file_iovec}
 \end{figure}
@@ -1129,14 +1123,14 @@ Pertanto se si modifica un file con l'interfaccia standard queste modifiche
 potranno essere visibili o meno a seconda del momento in cui la memoria
 virtuale trasporterà dal disco in memoria quella sezione del file, perciò è
 del tutto imprevedibile il risultato della modifica di un file nei confronti
 potranno essere visibili o meno a seconda del momento in cui la memoria
 virtuale trasporterà dal disco in memoria quella sezione del file, perciò è
 del tutto imprevedibile il risultato della modifica di un file nei confronti
-del contenuto della memoria mappata su cui è mappato.
-
-Per quanto appena visto, è sempre sconsigliabile eseguire scritture su file
-attraverso l'interfaccia standard, quando lo si è mappato in memoria, è invece
-possibile usare l'interfaccia standard per leggere un file mappato in memoria,
-purché si abbia una certa cura; infatti l'interfaccia dell'I/O mappato in
-memoria mette a disposizione la funzione \funcd{msync} per sincronizzare il
-contenuto della memoria mappata con il file su disco; il suo prototipo è:
+del contenuto della memoria su cui è mappato.
+
+Per questo, è sempre sconsigliabile eseguire scritture su file attraverso
+l'interfaccia standard, quando lo si è mappato in memoria, è invece possibile
+usare l'interfaccia standard per leggere un file mappato in memoria, purché si
+abbia una certa cura; infatti l'interfaccia dell'I/O mappato in memoria mette
+a disposizione la funzione \funcd{msync} per sincronizzare il contenuto della
+memoria mappata con il file su disco; il suo prototipo è:
 \begin{functions}  
   \headdecl{unistd.h}
   \headdecl{sys/mman.h} 
 \begin{functions}  
   \headdecl{unistd.h}
   \headdecl{sys/mman.h} 
@@ -1240,9 +1234,10 @@ processi scrivono, mescolando in maniera imprevedibile il loro output sul
 file.
 
 In tutti questi casi il \textit{file locking} è la tecnica che permette di
 file.
 
 In tutti questi casi il \textit{file locking} è la tecnica che permette di
-evitare le race condition, attraverso una serie di funzioni che permettono di
-bloccare l'accesso al file da parte di altri processi, così da evitare le
-sovrapposizioni, e garantire la atomicità delle operazioni di scrittura.
+evitare le race condition\index{race condition}, attraverso una serie di
+funzioni che permettono di bloccare l'accesso al file da parte di altri
+processi, così da evitare le sovrapposizioni, e garantire la atomicità delle
+operazioni di scrittura.
 
 
 
 
 
 
@@ -1507,18 +1502,10 @@ regione bloccata.
 \begin{figure}[!bht]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!bht]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct flock {
-    short int l_type;   /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
-    short int l_whence; /* Where `l_start' is relative to (like `lseek').  */
-    off_t l_start;      /* Offset where the lock begins.  */
-    off_t l_len;        /* Size of the locked area; zero means until EOF.  */
-    pid_t l_pid;        /* Process holding the lock.  */
-};
-    \end{lstlisting}
+    \includestruct{listati/flock.h}
   \end{minipage} 
   \normalsize 
   \end{minipage} 
   \normalsize 
-  \caption{La struttura \struct{flock}, usata da \func{fcntl} per il file
+  \caption{La struttura \structd{flock}, usata da \func{fcntl} per il file
     locking.} 
   \label{fig:struct_flock}
 \end{figure}
     locking.} 
   \label{fig:struct_flock}
 \end{figure}
@@ -1712,60 +1699,7 @@ necessario a soddisfare l'operazione richiesta.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
-    \begin{lstlisting}{}
-int main(int argc, char *argv[])
-{
-    int type = F_UNLCK;            /* lock type: default to unlock (invalid) */
-    off_t start = 0;             /* start of the locked region: default to 0 */
-    off_t len = 0;              /* length of the locked region: default to 0 */
-    int fd, res, i;                                    /* internal variables */
-    int bsd = 0;                          /* semantic type: default to POSIX */
-    int cmd = F_SETLK;              /* lock command: default to non-blocking */
-    struct flock lock;                                /* file lock structure */
-    ...
-    if ((argc - optind) != 1) {          /* There must be remaing parameters */
-        printf("Wrong number of arguments %d\n", argc - optind);
-        usage();
-    }
-    if (type == F_UNLCK) {            /* There must be a -w or -r option set */
-        printf("You should set a read or a write lock\n");
-        usage();
-    }
-    fd = open(argv[optind], O_RDWR);           /* open the file to be locked */
-    if (fd < 0) {                                           /* on error exit */
-        perror("Wrong filename");
-        exit(1);
-    }
-    /* do lock */
-    if (bsd) {                                             /* if BSD locking */
-        /* rewrite cmd for suitables flock operation values */ 
-        if (cmd == F_SETLKW) {                             /* if no-blocking */
-            cmd = LOCK_NB;              /* set the value for flock operation */
-        } else {                                                     /* else */
-            cmd = 0;                                      /* default is null */
-        }
-        if (type == F_RDLCK) cmd |= LOCK_SH;          /* set for shared lock */
-        if (type == F_WRLCK) cmd |= LOCK_EX;       /* set for exclusive lock */
-        res = flock(fd, cmd);                                /* esecute lock */
-    } else {                                             /* if POSIX locking */
-        /* setting flock structure */
-        lock.l_type = type;                       /* set type: read or write */
-        lock.l_whence = SEEK_SET;    /* start from the beginning of the file */
-        lock.l_start = start;          /* set the start of the locked region */
-        lock.l_len = len;             /* set the length of the locked region */
-        res = fcntl(fd, cmd, &lock);                              /* do lock */
-    }
-    /* check lock results */
-    if (res) {                                              /* on error exit */
-        perror("Failed lock");
-        exit(1);
-    } else {                                           /* else write message */
-        printf("Lock acquired\n");
-    }
-    pause();                       /* stop the process, use a signal to exit */
-    return 0;
-}
-    \end{lstlisting}
+    \includecodesample{listati/Flock.c}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del programma \file{Flock.c}.}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del programma \file{Flock.c}.}
@@ -2033,7 +1967,7 @@ opportune verifiche nei processi, questo verrebbe comunque rispettato.
 Per poter utilizzare il \textit{mandatory locking} è stato introdotto un
 utilizzo particolare del bit \acr{sgid}. Se si ricorda quanto esposto in
 \secref{sec:file_suid_sgid}), esso viene di norma utilizzato per cambiare il
 Per poter utilizzare il \textit{mandatory locking} è stato introdotto un
 utilizzo particolare del bit \acr{sgid}. Se si ricorda quanto esposto in
 \secref{sec:file_suid_sgid}), esso viene di norma utilizzato per cambiare il
-groupid effettivo con cui viene eseguito un programma, ed è pertanto sempre
+group-ID effettivo con cui viene eseguito un programma, ed è pertanto sempre
 associato alla presenza del permesso di esecuzione per il gruppo. Impostando
 questo bit su un file senza permesso di esecuzione in un sistema che supporta
 il \textit{mandatory locking}, fa sì che quest'ultimo venga attivato per il
 associato alla presenza del permesso di esecuzione per il gruppo. Impostando
 questo bit su un file senza permesso di esecuzione in un sistema che supporta
 il \textit{mandatory locking}, fa sì che quest'ultimo venga attivato per il