Integrate una altra serie di correzioni e riscritte parti coi suggerimenti
authorSimone Piccardi <piccardi@gnulinux.it>
Fri, 1 Mar 2002 18:47:21 +0000 (18:47 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Fri, 1 Mar 2002 18:47:21 +0000 (18:47 +0000)
di Alessio e Daniele.
Messa pure una sezione ringraziamenti, e aggiornato il ChangeLog, per
dare il relativo credito ai contributors ...

ChangeLog
fileintro.tex
gapil.tex
ipprot.tex
process.tex
prochand.tex
ringraziamenti.tex [new file with mode: 0644]

index f1a6a7bf5d313a21df76654865703d3180791f48..82287436fe9e94d422fd42949a0dce6bb9111899 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2002-03-01  Simone Piccardi  <piccardi@firenze.linux.it>
+
+       * prochand.tex: correzioni varie da D. Masini.
+
+       * process.tex: Spiegazione delle calling convention per le
+       pulitura dello stack da parte delle funzioni, contributo di
+       D. Masini, chiarimenti sui memory leak secondo quanto suggerito da
+       A. Frusciante.
+
+2002-02-28  Simone Piccardi  <piccardi@firenze.linux.it>
+
+       * prochand.tex: un altro blocco di correzioni suggerite da Daniele
+       Masini.  
+
 2002-02-27  Simone Piccardi  <piccardi@firenze.linux.it>
 
        * pref.tex, intro.tex, process.tex, prochand.tex: Correzioni
index 40d8e2575d262890ff440b6f165c95eb1f563537..15e2fd82fbd77d9004b4fccd7973c75d691d57c7 100644 (file)
@@ -90,10 +90,11 @@ risoluzione del nome (\textit{file name resolution} o \textit{pathname
   resolution}).  La risoluzione viene fatta esaminando il \textit{pathname} da
 sinistra a destra e localizzando ogni nome nella directory indicata dal nome
 precedente usando \file{/} come separatore\footnote{nel caso di nome vuoto, il
-  costrutto \file{//} viene considerato equivalente a \file{/}.}: ovviamente
-perché il procedimento funzioni occorre che i nomi indicati come directory
+  costrutto \file{//} viene considerato equivalente a \file{/}.}: ovviamente,
+perché il procedimento funzioni, occorre che i nomi indicati come directory
 esistano e siano effettivamente directory, inoltre i permessi (si veda
-\secref{sec:file_access_control}) devono consentire l'accesso.
+\secref{sec:file_access_control}) devono consentire l'accesso all'intero
+\textit{pathname}.
 
 Se il \textit{pathname} comincia per \file{/} la ricerca parte dalla directory
 radice del processo; questa, a meno di un \func{chroot} (su cui torneremo in
@@ -105,16 +106,16 @@ parte dalla directory corrente (su cui torneremo in
   relativo}\index{pathname relativo}.
 
 I nomi \file{.} e \file{..} hanno un significato speciale e vengono inseriti
-in ogni directory, il primo fa riferimento alla directory corrente e il
+in ogni directory: il primo fa riferimento alla directory corrente e il
 secondo alla directory \textsl{genitrice} (o \textit{parent directory}) cioè
 la directory che contiene il riferimento alla directory corrente; nel caso
-questa sia la directory radice allora il riferimento è a se stessa.
+questa sia la directory radice, allora il riferimento è a se stessa.
 
 
 \subsection{I tipi di file}
 \label{sec:file_file_types}
 
-Come detto in precedenza in Unix esistono vari tipi di file, in Linux questi
+Come detto in precedenza in Unix esistono vari tipi di file; in Linux questi
 sono implementati come oggetti del \textit{Virtual File System} (vedi
 \secref{sec:file_vfs_work}) e sono presenti in tutti i filesystem unix-like
 utilizzabili con Linux. L'elenco dei vari tipi di file definiti dal
@@ -143,10 +144,10 @@ dati) in base al loro contenuto, o tipo di accesso.
       un file che identifica una periferica ad accesso sequenziale \\
       \textit{block device} & \textsl{dispositivo a blocchi} &
       un file che identifica una periferica ad accesso diretto \\
-      \textit{fifo} & \textsl{``tubo''} &
+      \textit{fifo} & \textsl{``coda''} &
       un file speciale che identifica una linea di comunicazione software
       (unidirezionale) \\
-      \textit{socket} & \textsl{``spina''} &
+      \textit{socket} & \textsl{``presa''} &
       un file speciale che identifica una linea di comunicazione software
       (bidirezionale) \\
     \hline
@@ -160,27 +161,28 @@ VMS o Windows) 
 un flusso continuo di byte. Non esiste cioè differenza per come vengono visti
 dal sistema file di diverso contenuto o formato (come nel caso di quella fra
 file di testo e binari che c'è in Windows) né c'è una strutturazione a record
-per il cosiddetto ``accesso diretto'' come nel caso del VMS\footnote{con i
+per il cosiddetto ``accesso diretto'' come nel caso del VMS.\footnote{con i
   kernel della serie 2.4 è disponibile una forma di accesso diretto ai dischi
   (il \textit{raw access}) attraverso dei device file appositi, che però non
-  ha nulla a che fare con questo}.
+  ha nulla a che fare con questo.}
 
 Una seconda differenza è nel formato dei file ASCII; in Unix la fine riga è
-codificata in maniera diversa da Windows o Mac, in particolare il fine
-riga è il carattere \texttt{LF} (o \verb|\n|) al posto del \texttt{CR}
-(\verb|\r|) del Mac e del \texttt{CR LF} di Windows. Questo può causare alcuni
+codificata in maniera diversa da Windows o Mac, in particolare il fine riga è
+il carattere \texttt{LF} (o \verb|\n|) al posto del \texttt{CR} (\verb|\r|)
+del Mac e del \texttt{CR LF} di Windows.\footnote{per questo esistono in Linux
+  dei programmi come \cmd{unix2dos} e \cmd{dos2unix} che effettuano una
+  conversione fra questi due formati di testo.} Questo può causare alcuni
 problemi qualora nei programmi si facciano assunzioni sul terminatore della
 riga.
 
 Si ricordi infine che in ambiente Unix non esistono tipizzazioni dei file di
 dati e che non c'è nessun supporto del sistema per le estensioni come parte
-del filesystem. Ciò non ostante molti programmi adottano delle convenzioni per
+del filesystem. Ciò nonostante molti programmi adottano delle convenzioni per
 i nomi dei file, ad esempio il codice C normalmente si mette in file con
 l'estensione \file{.c}, ma questa è, per quanto usata ed accettata in maniera
 universale, solo una convenzione.
 
 
-
 \subsection{Le due interfacce ai file}
 \label{sec:file_io_api}
 
@@ -203,21 +205,21 @@ rappresentati da numeri interi (cio
 L'interfaccia è definita nell'header \file{unistd.h}.
 
 La seconda interfaccia è quella che il manuale della \acr{glibc} chiama degli
-\textit{stream}\index{stream}, essa provvede funzioni più evolute e un accesso
+\textit{stream}\index{stream}. Essa provvede funzioni più evolute e un accesso
 bufferizzato (controllato dalla implementazione fatta dalle \acr{glibc}), la
 tratteremo in dettaglio nel \capref{cha:files_std_interface}.
 
 Questa è l'interfaccia standard specificata dall'ANSI C e perciò si trova
 anche su tutti i sistemi non Unix. Gli \textit{stream} sono oggetti complessi
 e sono rappresentati da puntatori ad un opportuna struttura definita dalle
-librerie del C, si accede ad essi sempre in maniera indiretta utilizzando il
+librerie del C; si accede ad essi sempre in maniera indiretta utilizzando il
 tipo \type{FILE *}.  L'interfaccia è definita nell'header \type{stdio.h}.
 
 Entrambe le interfacce possono essere usate per l'accesso ai file come agli
 altri oggetti del VFS (pipe, socket, device, sui quali torneremo in dettaglio
 a tempo opportuno), ma per poter accedere alle operazioni di controllo su un
 qualunque tipo di oggetto del VFS occorre usare l'interfaccia standard di Unix
-coi \textit{file descriptor}. Allo stesso modo devono essere usati i
+coi \textit{file descriptor}. Allo stesso modo devono essere usati i
 \textit{file descriptor} se si vuole ricorrere a modalità speciali di I/O come
 il polling o il non-bloccante (vedi \capref{cha:file_advanced}).
 
index 25211c92f5d72e46bd074fb55028ff5ec94f1d85..36fc3c77568d729802ecfb0a8204f04d1a0d222e 100644 (file)
--- a/gapil.tex
+++ b/gapil.tex
 \include{ipprot}
 \include{tcpprot}
 \include{errors}
+\include{ringraziamenti}
 \include{fdl}
 
 % at the end put the bibliography
index 4618a30faf1d02f522eab01c1108c494fbffdb8c..11954fa90e9d3d28900d136e37e6e6b0f900facf 100644 (file)
@@ -752,11 +752,12 @@ prima di avere un indirizzo globale.
 \end{table}
 
 Ci sono due tipi di indirizzi, \textit{link-local} e \textit{site-local}. Il
-primo è usato per un singolo link; la struttura è mostrata in \curtab, questi
-indirizzi iniziano sempre per \texttt{FE80} e vengono in genere usati per la
-configurazione automatica dell'indirizzo al bootstrap e per la ricerca dei
-vicini (vedi \ref{sec:IP_ipv6_autoconf}); un pacchetto che abbia tale
-indirizzo come sorgente o destinazione non deve venire ritrasmesso dai router.
+primo è usato per un singolo link; la struttura è mostrata in
+\tabref{tab:IP_ipv6_linklocal}, questi indirizzi iniziano sempre per
+\texttt{FE80} e vengono in genere usati per la configurazione automatica
+dell'indirizzo al bootstrap e per la ricerca dei vicini (vedi
+\ref{sec:IP_ipv6_autoconf}); un pacchetto che abbia tale indirizzo come
+sorgente o destinazione non deve venire ritrasmesso dai router.
 
 Un indirizzo \textit{site-local} invece è usato per l'indirizzamento
 all'interno di un sito che non necessita di un prefisso globale; la struttura
index 935f34e5f6c67f14f4b7d3dc87781408e0e4345d..483fbb9a9bbdd10cb8b06e3b7e5398425e31dcab 100644 (file)
@@ -380,7 +380,10 @@ programma C viene suddiviso nei seguenti segmenti:
   del chiamante (tipo il contenuto di alcuni registri della CPU). Poi la
   funzione chiamata alloca qui lo spazio per le sue variabili locali: in
   questo modo le funzioni possono essere chiamate ricorsivamente. Al ritorno
-  della funzione lo spazio è automaticamente rilasciato.
+  della funzione lo spazio è automaticamente rilasciato. Al ritorno della
+  funzione lo spazio è automaticamente ripulito. La pulizia in C e C++ viene
+  fatta dal chiamante.\footnote{a meno che non sia stato specificato
+    l'utilizzo di una calling convention diversa da quella standard.}
   
   La dimensione di questo segmento aumenta seguendo la crescita dello stack
   del programma, ma non viene ridotta quando quest'ultimo si restringe.
@@ -538,15 +541,18 @@ routine di allocazione 
 non più utilizzata, quello che in inglese viene chiamato \textit{memory-leak},
 (cioè \textsl{perdita di memoria}).
 
-Un caso tipico che illustra il problema è quello in cui l'allocazione di una
-variabile viene fatta da una subroutine per un uso locale, ma la memoria non
-viene liberata; la funzione esce e la memoria resta allocata (fino alla
-terminazione del processo).  Chiamate ripetute alla stessa subroutine
-continueranno ad allocarne ancora, causando a lungo andare un esaurimento
-della memoria disponibile e l'impossibilità di proseguire il programma. Il
-problema è che l'esaurimento che può avvenire in qualunque momento, e senza
-nessuna relazione con la subroutine che contiene l'errore, per questo motivo è
-sempre complesso trovare un \textit{memory leak}.
+Un caso tipico che illustra il problema è quello in cui in una subroutine si
+alloca della memoria per uso locale senza liberarla prima di uscire. La
+memoria resta così allocata fino alla terminazione del processo.  Chiamate
+ripetute alla stessa subroutine continueranno ad effettuare altre allocazioni,
+causando a lungo andare un esaurimento della memoria disponibile (e la
+probabile l'impossibilità di proseguire l'esecuzione programma).
+
+Il problema è che l'esaurimento della memoria può avvenire in qualunque
+momento, in corrispondenza ad una qualunque chiamata di \func{malloc}, che può
+essere in una sezione del codice che non ha alcuna relazione con la subroutine
+che contiene l'errore. Per questo motivo è sempre molto difficile trovare un
+\textit{memory leak}.
 
 Per ovviare a questi problemi l'implementazione delle routine di allocazione
 delle \acr{glibc} mette a disposizione una serie di funzionalità (su cui
@@ -1173,7 +1179,7 @@ problematiche generali che possono emergere nella programmazione e di quali
 precauzioni o accorgimenti occorre prendere per risolverle. Queste
 problematiche non sono specifiche di sistemi unix-like o multitasking, ma
 avendo trattato in questo capitolo il comportamento dei processi visti come
-entità a se stanti, le riportiamo qui.
+entità a sé stanti, le riportiamo qui.
 
 
 \subsection{Il passaggio delle variabili e dei valori di ritorno}
@@ -1258,8 +1264,8 @@ inoltre che l'ultimo degli argomenti fissi sia di tipo
   per compatibilità; ad esempio i tipi \type{float} vengono convertiti
   automaticamente a \type{double} ed i \type{char} e gli \type{short} ad
   \type{int}. Un tipo \textit{self-promoting} è un tipo che verrebbe promosso
-  a se stesso.} il che esclude array, puntatori a funzioni e interi di tipo
-\type{char} o \type{short} (con segno o meno). Un'ulteriore restrizione di
+  a sé stesso.} il che esclude array, puntatori a funzioni e interi di tipo
+\type{char} o \type{short} (con segno o meno). Una restrizione ulteriore di
 alcuni compilatori è di non dichiarare l'ultimo parametro fisso come
 \type{register}.
 
@@ -1284,7 +1290,7 @@ in generale 
 potrebbero essere stati effettivamente forniti, e nella esecuzione delle
 \macro{va\_arg} ci si può fermare in qualunque momento ed i restanti argomenti
 saranno ignorati; se invece si richiedono più argomenti di quelli forniti si
-otterranno dei valori indefiniti. Nel caso del \cmd{gcc} poi l'uso della macro
+otterranno dei valori indefiniti. Nel caso del \cmd{gcc} l'uso della macro
 \macro{va\_end} è inutile, ma si consiglia di usarlo ugualmente per
 compatibilità.
 
@@ -1334,7 +1340,7 @@ motivo \macro{va\_list} 
 direttamente ad un altra variabile dello stesso tipo. Per risolvere questo
 problema lo standard ISO C99\footnote{alcuni sistemi che non hanno questa
   macro provvedono al suo posto \macro{\_\_va\_copy} che era il nome proposto
-  in una bozza dello standard} ha previsto un'ulteriore macro che permette di
+  in una bozza dello standard} ha previsto una macro ulteriore che permette di
 eseguire la copia di un puntatore alla lista degli argomenti:
 \begin{prototype}{stdarg.h}{void va\_copy(va\_list dest, va\_list src)}
   Copia l'attuale valore \param{src} del puntatore alla lista degli argomenti
@@ -1395,10 +1401,12 @@ dinamicamente con una delle funzioni della famiglia \func{malloc}.
 \label{sec:proc_longjmp}
 
 Il controllo del flusso di un programma in genere viene effettuato con le
-varie istruzioni del linguaggio C, la più bistrattata delle quali è il
-\code{goto}, ampiamente deprecato in favore di costrutti più puliti; esiste
-però un caso in l'uso di questa istruzione porta all'implementazione più
-efficiente, quello dell'uscita in caso di errore.
+varie istruzioni del linguaggio C; fra queste la più bistrattata è il
+\code{goto}, che viene deprecato in favore dei costrutti della programmazione
+strutturata, che rendono il codice più leggibile e mantenibile . Esiste però
+un caso in cui l'uso di questa istruzione porta all'implementazione più
+efficiente e chiara anche dal punto di vista della struttura del programma,
+quello dell'uscita in caso di errore.
 
 Il C però non consente di effettuare un salto ad una label definita in
 un'altra funzione, per cui se l'errore avviene in funzioni profondamente
@@ -1406,7 +1414,6 @@ annidate occorre usare quello che viene chiamato un salto \textsl{non-locale};
 questo viene fatto usando salvando il contesto dello stack nel punto in cui si
 vuole tornare in caso di errore, e ripristinandolo quando l'occorrenza capita.
 
-
 La funzione che permette di salvare il contesto dello stack è \func{setjmp},
 il cui prototipo è:
 
index dcad87688627b3e71577586a24b12835bb8941a4..38a9b2f18799685c4e5c23a94ce5279a33f37521 100644 (file)
@@ -14,13 +14,12 @@ finale introdurremo alcune problematiche generiche della programmazione in
 ambiente multitasking.
 
 
-
 \section{Introduzione}
 \label{sec:proc_gen}
 
-Inizieremo con una introduzione generale ai concetti che stanno alla base
-della gestione dei processi in un sistema unix-like. Introdurremo in questa
-sezione l'architettura della gestione dei processi e le sue principali
+Inizieremo con un'introduzione generale ai concetti che stanno alla base della
+gestione dei processi in un sistema unix-like. Introdurremo in questa sezione
+l'architettura della gestione dei processi e le sue principali
 caratteristiche, dando una panoramica sull'uso delle principali funzioni di
 gestione.
 
@@ -37,9 +36,9 @@ numero unico, il cosiddetto \textit{process identifier} o, pi
 \acr{pid}.
 
 Una seconda caratteristica di un sistema Unix è che la generazione di un
-processo è unoperazione separata rispetto al lancio di un programma. In
+processo è un'operazione separata rispetto al lancio di un programma. In
 genere la sequenza è sempre quella di creare un nuovo processo, il quale
-eseguirà, in un passo successivo, il programma voluto: questo è ad esempio
+eseguirà, in un passo successivo, il programma desiderato: questo è ad esempio
 quello che fa la shell quando mette in esecuzione il programma che gli
 indichiamo nella linea di comando.
 
@@ -107,10 +106,10 @@ Dato che tutti i processi attivi nel sistema sono comunque generati da
   vero, in Linux ci sono alcuni processi che pur comparendo come figli di
   init, o con \acr{pid} successivi, sono in realtà generati direttamente dal
   kernel, (come \cmd{keventd}, \cmd{kswapd}, etc.)} si possono classificare i
-processi con la relazione padre/figlio in unorganizzazione gerarchica ad
+processi con la relazione padre/figlio in un'organizzazione gerarchica ad
 albero, in maniera analoga a come i file sono organizzati in un albero di
 directory (si veda \secref{sec:file_organization}); in \curfig\ si è mostrato
-il risultato del comando \cmd{pstree} che permette di mostrare questa
+il risultato del comando \cmd{pstree} che permette di visualizzare questa
 struttura, alla cui base c'è \cmd{init} che è progenitore di tutti gli altri
 processi.
 
@@ -162,7 +161,7 @@ figlio sono affrontate in dettaglio in \secref{sec:proc_fork}).
 Se si vuole che il processo padre si fermi fino alla conclusione del processo
 figlio questo deve essere specificato subito dopo la \func{fork} chiamando la
 funzione \func{wait} o la funzione \func{waitpid} (si veda
-\secref{sec:proc_wait}); queste funzioni restituiscono anche uninformazione
+\secref{sec:proc_wait}); queste funzioni restituiscono anche un'informazione
 abbastanza limitata sulle cause della terminazione del processo figlio.
 
 Quando un processo ha concluso il suo compito o ha incontrato un errore non
@@ -182,8 +181,8 @@ coi processi che 
 Il programma che un processo sta eseguendo si chiama immagine del processo (o
 \textit{process image}), le funzioni della famiglia \func{exec} permettono di
 caricare un'altro programma da disco sostituendo quest'ultimo all'immagine
-corrente; questo fa si che l'immagine precedente venga completamente
-cancellata. Questo significa che quando il nuovo programma esce anche il
+corrente; questo fa sì che l'immagine precedente venga completamente
+cancellata. Questo significa che quando il nuovo programma esce, anche il
 processo termina, e non si può tornare alla precedente immagine.
 
 Per questo motivo la \func{fork} e la \func{exec} sono funzioni molto
@@ -207,17 +206,18 @@ programmi.
 \subsection{Gli identificatori dei processi}
 \label{sec:proc_pid}
 
-Come accennato nell'introduzione ogni processo viene identificato dal sistema
+Come accennato nell'introduzione, ogni processo viene identificato dal sistema
 da un numero identificativo unico, il \textit{process id} o \acr{pid};
 quest'ultimo è un tipo di dato standard, il \type{pid\_t} che in genere è un
-intero con segno (nel caso di Linux e delle \acr{glibc} il tipo usato è \type{int}).
+intero con segno (nel caso di Linux e delle \acr{glibc} il tipo usato è
+\type{int}).
 
 Il \acr{pid} viene assegnato in forma progressiva ogni volta che un nuovo
 processo viene creato, fino ad un limite massimo (in genere essendo detto
 numero memorizzato in un intero a 16 bit si arriva a 32767) oltre il quale si
 riparte dal numero più basso disponibile\footnote{FIXME: verificare, non sono
-  sicuro}.  Per questo motivo processo il processo di avvio (\cmd{init}) ha
-sempre il \acr{pid} uguale a uno.
+  sicuro}.  Per questo motivo, come visto in \secref{sec:proc_hierarchy}, il
+processo di avvio (\cmd{init}) ha sempre il \acr{pid} uguale a uno.
 
 Tutti i processi inoltre memorizzano anche il \acr{pid} del genitore da cui
 sono stati creati, questo viene chiamato in genere \acr{ppid} (da
@@ -273,9 +273,9 @@ prototipo della funzione 
   \funcdecl{pid\_t fork(void)} 
   Crea un nuovo processo.
   
-  \bodydesc{Restituisce zero al padre e il \acr{pid} al figlio in caso di
-    successo, ritorna -1 al padre (senza creare il figlio) in caso di errore;
-    \var{errno} può assumere i valori:
+  \bodydesc{In caso di successo restituisce il \acr{pid} del figlio al padre e
+    zero al figlio; ritorna -1 al padre (senza creare il figlio) in caso di
+    errore; \var{errno} può assumere i valori:
   \begin{errlist}
   \item[\macro{EAGAIN}] non ci sono risorse sufficienti per creare un'altro
     processo (per allocare la tabella delle pagine e le strutture del task) o
@@ -286,12 +286,12 @@ prototipo della funzione 
 \end{functions}
 
 Dopo il successo dell'esecuzione di una \func{fork} sia il processo padre che
-il processo figlio continuano ad essere eseguiti normalmente allistruzione
+il processo figlio continuano ad essere eseguiti normalmente all'istruzione
 seguente la \func{fork}; il processo figlio è però una copia del padre, e
 riceve una copia dei segmenti di testo, stack e dati (vedi
 \secref{sec:proc_mem_layout}), ed esegue esattamente lo stesso codice del
-padre. Si tenga presente però che la memoria è copiata, non condivisa, pertanto
-padre e figlio vedono variabili diverse.
+padre. Si tenga presente però che la memoria è copiata, non condivisa,
+pertanto padre e figlio vedono variabili diverse.
 
 Per quanto riguarda la gestione della memoria in generale il segmento di
 testo, che è identico, è condiviso e tenuto in read-only per il padre e per i
@@ -392,7 +392,7 @@ operazione che viene chiamata \textit{spawn}. Nei sistemi unix-like 
 scelto di mantenere questa separazione, dato che, come per la prima modalità
 d'uso, esistono numerosi scenari in cui si può usare una \func{fork} senza
 aver bisogno di eseguire una \func{exec}. Inoltre, anche nel caso della
-seconda modalità duso, avere le due funzioni separate permette al figlio di
+seconda modalità d'uso, avere le due funzioni separate permette al figlio di
 cambiare gli attributi del processo (maschera dei segnali, redirezione
 dell'output, \textit{user id}) prima della \func{exec}, rendendo così
 relativamente facile intervenire sulle le modalità di esecuzione del nuovo
@@ -401,11 +401,14 @@ programma.
 In \curfig\ si è riportato il corpo del codice del programma di esempio
 \cmd{forktest}, che ci permette di illustrare molte caratteristiche dell'uso
 della funzione \func{fork}. Il programma permette di creare un numero di figli
-specificato a linea di comando, e prende anche alcune opzioni per indicare
+specificato da linea di comando, e prende anche alcune opzioni per indicare
 degli eventuali tempi di attesa in secondi (eseguiti tramite la funzione
 \func{sleep}) per il padre ed il figlio (con \cmd{forktest -h} si ottiene la
 descrizione delle opzioni); il codice completo, compresa la parte che gestisce
-le opzioni a riga di comando, è disponibile nel file \file{ForkTest.c}.
+le opzioni a riga di comando, è disponibile nel file \file{ForkTest.c},
+distribuito insieme agli altri sorgenti degli esempi su
+\href{http://firenze.linux.it/~piccardi/gapil_source.tgz}
+{\texttt{http://firenze.linux.it/\~~\hspace{-2.0mm}piccardi/gapil\_source.tgz}}.
 
 Decifrato il numero di figli da creare, il ciclo principale del programma
 (\texttt{\small 24--40}) esegue in successione la creazione dei processi figli
@@ -441,8 +444,8 @@ Go to next child
 \end{verbatim} %$
 \normalsize
 
-Esaminiamo questo risultato: una prima conclusione che si può trarre è non si
-può dire quale processo fra il padre ed il figlio venga eseguito per
+Esaminiamo questo risultato: una prima conclusione che si può trarre è che non
+si può dire quale processo fra il padre ed il figlio venga eseguito per
 primo\footnote{a partire dal kernel 2.5.2-pre10 è stato introdotto il nuovo
   scheduler di Ingo Molnar che esegue sempre per primo il figlio; per
   mantenere la portabilità è opportuno non fare comunque affidamento su questo
@@ -463,7 +466,7 @@ cui il processo padre ha eseguito pi
 figli venisse messo in esecuzione.
 
 Pertanto non si può fare nessuna assunzione sulla sequenza di esecuzione delle
-istruzioni del codice fra padre e figli, nè sull'ordine in cui questi potranno
+istruzioni del codice fra padre e figli, né sull'ordine in cui questi potranno
 essere messi in esecuzione. Se è necessaria una qualche forma di precedenza
 occorrerà provvedere ad espliciti meccanismi di sincronizzazione, pena il
 rischio di incorrere nelle cosiddette \textit{race condition} \index{race
@@ -472,9 +475,9 @@ rischio di incorrere nelle cosiddette \textit{race condition} \index{race
 Si noti inoltre che essendo i segmenti di memoria utilizzati dai singoli
 processi completamente separati, le modifiche delle variabili nei processi
 figli (come l'incremento di \var{i} in \texttt{\small 31}) sono visibili solo
-a loro, e non hanno alcun effetto sul valore che le stesse variabili hanno nel
-processo padre (ed in eventuali altri processi figli che eseguano lo stesso
-codice).
+a loro (ogni processo vede solo la propria copia della memoria), e non hanno
+alcun effetto sul valore che le stesse variabili hanno nel processo padre (ed
+in eventuali altri processi figli che eseguano lo stesso codice).
 
 Un secondo aspetto molto importante nella creazione dei processi figli è
 quello dell'interazione dei vari processi con i file; per illustrarlo meglio
@@ -687,7 +690,7 @@ eseguite alla chiusura di un processo 
 
 Oltre queste operazioni è però necessario poter disporre di un meccanismo
 ulteriore che consenta di sapere come la terminazione è avvenuta: dato che in
-un sistema unix-like tutto viene gestito attraverso i processi il meccanismo
+un sistema unix-like tutto viene gestito attraverso i processi, il meccanismo
 scelto consiste nel riportare lo stato di terminazione (il cosiddetto
 \textit{termination status}) al processo padre.
 
@@ -715,7 +718,7 @@ terminato (si potrebbe avere cio
 
 Questa complicazione viene superata facendo in modo che il processo orfano
 venga \textsl{adottato} da \cmd{init}. Come già accennato quando un processo
-termina il kernel controlla se è il padre di altri processi in esecuzione: in
+termina, il kernel controlla se è il padre di altri processi in esecuzione: in
 caso positivo allora il \acr{ppid} di tutti questi processi viene sostituito
 con il \acr{pid} di \cmd{init} (e cioè con 1); in questo modo ogni processo
 avrà sempre un padre (nel caso possiamo parlare di un padre \textsl{adottivo})
@@ -932,7 +935,7 @@ per leggerne lo stato di chiusura (ed evitare la presenza di \textit{zombie}),
 per questo la modalità più usata per chiamare queste funzioni è quella di
 utilizzarle all'interno di un \textit{signal handler} (torneremo sui segnali e
 su come gestire \macro{SIGCHLD} in \secref{sec:sig_sigwait_xxx}). In questo
-caso infatti, dato che il segnale è generato dalla terminazione un figlio,
+caso infatti, dato che il segnale è generato dalla terminazione di un figlio,
 avremo la certezza che la chiamata a \func{wait} non si bloccherà.
 
 \begin{table}[!htb]
@@ -986,12 +989,12 @@ anomala), uno per indicare se 
 
 Lo standard POSIX.1 definisce una serie di macro di preprocessore da usare per
 analizzare lo stato di uscita. Esse sono definite sempre in
-\file{<sys/wait.h>} ed elencate in \curtab\ (si tenga presente che queste
-macro prendono come parametro la variabile di tipo \type{int} puntata da
-\var{status}).
+\file{<sys/wait.h>} ed elencate in \tabref{tab:proc_status_macro} (si tenga
+presente che queste macro prendono come parametro la variabile di tipo
+\type{int} puntata da \var{status}).
 
 Si tenga conto che nel caso di conclusione anomala il valore restituito da
-\macro{WTERMSIG} può essere controllato contro le costanti definite in
+\macro{WTERMSIG} può essere confrontato con le costanti definite in
 \file{signal.h} ed elencate in \tabref{tab:sig_signal_list}, e stampato usando
 le apposite funzioni trattate in \secref{sec:sig_strsignal}.
 
@@ -999,7 +1002,7 @@ le apposite funzioni trattate in \secref{sec:sig_strsignal}.
 \subsection{Le funzioni \func{wait3} e \func{wait4}}
 \label{sec:proc_wait4}
 
-Linux, seguendo unestensione di BSD, supporta altre due funzioni per la
+Linux, seguendo un'estensione di BSD, supporta altre due funzioni per la
 lettura dello stato di terminazione di un processo \func{wait3} e
 \func{wait4}, analoghe alle precedenti ma che prevedono un ulteriore
 parametro attraverso il quale il kernel può restituire al padre informazioni
@@ -1164,11 +1167,12 @@ specificare il comando da eseguire; quando il parametro \var{file} non
 contiene una \file{/} esso viene considerato come un nome di programma, e
 viene eseguita automaticamente una ricerca fra i file presenti nella lista di
 directory specificate dalla variabile di ambiente \var{PATH}. Il file che
-viene posto in esecuzione è il primo che viene trovato. Se si ha un errore di
-permessi negati (cioè l'esecuzione della sottostante \func{execve} ritorna un
-\macro{EACCESS}), la ricerca viene proseguita nelle eventuali ulteriori
-directory indicate nel \var{PATH}, solo se non viene trovato nessun altro file
-viene finalmente restituito \macro{EACCESS}.
+viene posto in esecuzione è il primo che viene trovato. Se si ha un errore
+relativo a permessi di accesso insufficienti (cioè l'esecuzione della
+sottostante \func{execve} ritorna un \macro{EACCESS}), la ricerca viene
+proseguita nelle eventuali ulteriori directory indicate in \var{PATH}; solo se
+non viene trovato nessun altro file viene finalmente restituito
+\macro{EACCESS}.
 
 Le altre quattro funzioni si limitano invece a cercare di eseguire il file
 indicato dal parametro \var{path}, che viene interpretato come il
@@ -1177,7 +1181,7 @@ indicato dal parametro \var{path}, che viene interpretato come il
 \begin{figure}[htb]
   \centering
   \includegraphics[width=13cm]{img/exec_rel}
-  \caption{La interrelazione fra le sei funzioni della famiglia \func{exec}}
+  \caption{La interrelazione fra le sei funzioni della famiglia \func{exec}.}
   \label{fig:proc_exec_relat}
 \end{figure}
 
@@ -1213,12 +1217,11 @@ la lista completa 
   \var{tms\_cutime}, \var{tms\_ustime} (vedi \secref{sec:xxx_xxx}).
 \end{itemize*}
 
-Oltre a questo i segnali che sono stati settati per essere ignorati nel
-processo chiamante mantengono lo stesso settaggio pure nel nuovo programma,
-tutti gli altri segnali vengono settati alla loro azione di default. Un caso
-speciale è il segnale \macro{SIGCHLD} che, quando settato a \macro{SIG\_IGN},
-può anche non essere resettato a \macro{SIG\_DFL} (si veda
-\secref{sec:sig_gen_beha}).
+Inoltre i segnali che sono stati settati per essere ignorati nel processo
+chiamante mantengono lo stesso settaggio pure nel nuovo programma, tutti gli
+altri segnali vengono settati alla loro azione di default. Un caso speciale è
+il segnale \macro{SIGCHLD} che, quando settato a \macro{SIG\_IGN}, può anche
+non essere resettato a \macro{SIG\_DFL} (si veda \secref{sec:sig_gen_beha}).
 
 La gestione dei file aperti dipende dal valore che ha il flag di
 \textit{close-on-exec} (trattato in \secref{sec:file_fcntl}) per ciascun file
@@ -1227,7 +1230,7 @@ restano aperti. Questo significa che il comportamento di default 
 restano aperti attraverso una \func{exec}, a meno di una chiamata esplicita a
 \func{fcntl} che setti il suddetto flag.
 
-Per le directory lo standard POSIX.1 richiede che esse vengano chiuse
+Per le directory, lo standard POSIX.1 richiede che esse vengano chiuse
 attraverso una \func{exec}, in genere questo è fatto dalla funzione
 \func{opendir} (vedi \secref{sec:file_dir_read}) che effettua da sola il
 settaggio del flag di \textit{close-on-exec} sulle directory che apre, in
@@ -1356,13 +1359,13 @@ identificatori ai valori corrispondenti all'utente che entra nel sistema.
 
 Al secondo gruppo appartengono l'\textit{effective user id} e
 l'\textit{effective group id} (a cui si aggiungono gli eventuali
-\textit{supplementary group id} dei gruppi dei quale l'utente fa parte).
+\textit{supplementary group id} dei gruppi dei quali l'utente fa parte).
 Questi sono invece gli identificatori usati nella verifiche dei permessi del
 processo e per il controllo di accesso ai file (argomento affrontato in
 dettaglio in \secref{sec:file_perm_overview}). 
 
 Questi identificatori normalmente sono identici ai corrispondenti del gruppo
-\textsl{reale} tranne nel caso in cui, come accennato in
+\textit{real} tranne nel caso in cui, come accennato in
 \secref{sec:proc_exec}, il programma che si è posto in esecuzione abbia i bit
 \acr{suid} o \acr{sgid} settati (il significato di questi bit è affrontato in
 dettaglio in \secref{sec:file_suid_sgid}). In questo caso essi saranno settati
@@ -1401,10 +1404,10 @@ servano di nuovo.
 Questo in Linux viene fatto usando altri due gruppi di identificatori, il
 \textit{saved} ed il \textit{filesystem}, analoghi ai precedenti. Il primo
 gruppo è lo stesso usato in SVr4, e previsto dallo standard POSIX quando è
-definita la costante \macro{\_POSIX\_SAVED\_IDS}\footnote{in caso si abbia a
+definita la costante \macro{\_POSIX\_SAVED\_IDS},\footnote{in caso si abbia a
   cuore la portabilità del programma su altri Unix è buona norma controllare
   sempre la disponibilità di queste funzioni controllando se questa costante è
-  definita}, il secondo gruppo è specifico di Linux e viene usato per
+  definita.} il secondo gruppo è specifico di Linux e viene usato per
 migliorare la sicurezza con NFS.
 
 Il \textit{saved user id} e il \textit{saved group id} sono copie
@@ -1473,7 +1476,7 @@ riportare l'\textit{effective user id} a quello dell'utente che ha lanciato il
 programma, effettuare il lavoro che non necessita di privilegi aggiuntivi, ed
 eventualmente tornare indietro.
 
-Come esempio per chiarire dell'uso di queste funzioni prendiamo quello con cui
+Come esempio per chiarire l'uso di queste funzioni prendiamo quello con cui
 viene gestito l'accesso al file \file{/var/log/utmp}.  In questo file viene
 registrato chi sta usando il sistema al momento corrente; chiaramente non può
 essere lasciato aperto in scrittura a qualunque utente, che potrebbe
@@ -1484,7 +1487,7 @@ esempio tutti i programmi di terminale in X, o il programma \cmd{screen} che
 crea terminali multipli su una console) appartengono a questo gruppo ed hanno
 il bit \acr{sgid} settato.
 
-Quando uno di questi programmi (ad esempio \cmd{xterm}) viene lanciato la
+Quando uno di questi programmi (ad esempio \cmd{xterm}) viene lanciato, la
 situazione degli identificatori è la seguente:
 \begin{eqnarray*}
   \label{eq:1}
@@ -1493,7 +1496,7 @@ situazione degli identificatori 
   \textit{saved group id}     &=& \textrm{\acr{utmp}}
 \end{eqnarray*}
 in questo modo, dato che l'\textit{effective group id} è quello giusto, il
-programma può accedere a \file{/var/log/utmp} in scrittura ed aggiornarlo, a
+programma può accedere a \file{/var/log/utmp} in scrittura ed aggiornarlo. A
 questo punto il programma può eseguire una \code{setgid(getgid())} per settare
 l'\textit{effective group id} a quello dell'utente (e dato che il \textit{real
   group id} corrisponde la funzione avrà successo), in questo modo non sarà
@@ -1509,9 +1512,9 @@ e ogni processo lanciato dal terminale avrebbe comunque \acr{gid} come
 \textit{effective group id}. All'uscita dal terminale, per poter di nuovo
 aggiornare lo stato di \file{/var/log/utmp} il programma eseguirà una
 \code{setgid(utmp)} (dove \var{utmp} è il valore numerico associato al gruppo
-\acr{utmp}, ottenuto ad esempio con una \func{getegid}), dato che in questo
-caso il valore richiesto corrisponde al \textit{saved group id} la funzione
-avrà successo e riporterà la situazione a:
+\acr{utmp}, ottenuto ad esempio con una precedente \func{getegid}), dato che
+in questo caso il valore richiesto corrisponde al \textit{saved group id} la
+funzione avrà successo e riporterà la situazione a:
 \begin{eqnarray*}
   \label{eq:3}
   \textit{real group id}      &=& \textrm{\acr{gid} (invariato)}  \\
@@ -1580,7 +1583,7 @@ Lo stesso problema di propagazione dei privilegi ad eventuali processi figli
 si porrebbe per i \textit{saved id}: queste funzioni derivano da
 un'implementazione che non ne prevede la presenza, e quindi non è possibile
 usarle per correggere la situazione come nel caso precedente. Per questo
-motivo in Linux tutte le volte che vengono usata per modificare uno degli
+motivo in Linux tutte le volte che vengono usate per modificare uno degli
 identificatori ad un valore diverso dal \textit{real id} precedente, il
 \textit{saved id} viene sempre settato al valore dell'\textit{effective id}.
 
@@ -1616,7 +1619,7 @@ il settaggio di tutti gli identificatori.
 \subsection{Le funzioni \func{setresuid} e \func{setresgid}}
 \label{sec:proc_setresuid}
 
-Queste due funzioni sono unestensione introdotta in Linux dal kernel 2.1.44,
+Queste due funzioni sono un'estensione introdotta in Linux dal kernel 2.1.44,
 e permettono un completo controllo su tutti gli identificatori (\textit{real},
 \textit{effective} e \textit{saved}), i prototipi sono:
 \begin{functions}
@@ -1663,7 +1666,7 @@ prototipi sono:
   variabili di ritorno non sono validi.}
 \end{functions}
 
-Anche queste funzioni sono unestensione specifica di Linux, e non richiedono
+Anche queste funzioni sono un'estensione specifica di Linux, e non richiedono
 nessun privilegio. I valori sono restituiti negli argomenti, che vanno
 specificati come puntatori (è un'altro esempio di \textit{value result
   argument}). Si noti che queste funzioni sono le uniche in grado di leggere i
@@ -1715,11 +1718,10 @@ coincide con uno dei \textit{real}, \textit{effective} o \textit{saved id}.
 \subsection{Le funzioni \func{setgroups} e \func{getgroups}}
 \label{sec:proc_setgroups}
 
-Le ultime funzioni che esamineremo sono quelle sono quelle che permettono di
-operare sui gruppi supplementari. Ogni processo può avere fino a
-\macro{NGROUPS\_MAX} gruppi supplementari in aggiunta al gruppo primario,
-questi vengono ereditati dal processo padre e possono essere cambiati con
-queste funzioni.
+Le ultime funzioni che esamineremo sono quelle che permettono di operare sui
+gruppi supplementari. Ogni processo può avere fino a \macro{NGROUPS\_MAX}
+gruppi supplementari in aggiunta al gruppo primario, questi vengono ereditati
+dal processo padre e possono essere cambiati con queste funzioni.
 
 La funzione che permette di leggere i gruppi supplementari è \func{getgroups};
 questa funzione è definita nello standard POSIX ed il suo prototipo è:
@@ -1760,8 +1762,8 @@ ottenere tutti i gruppi a cui appartiene un utente; il suo prototipo 
 \noindent la funzione esegue una scansione del database dei gruppi (si veda
 \secref{sec:sys_user_group}) e ritorna in \param{groups} la lista di quelli a
 cui l'utente appartiene. Si noti che \param{ngroups} è passato come puntatore
-perché qualora il valore specificato sia troppo piccolo la funzione ritorna -1
-e passando indietro il numero dei gruppi trovati.
+perché qualora il valore specificato sia troppo piccolo la funzione ritorna
+-1, passando indietro il numero dei gruppi trovati.
 
 Per settare i gruppi supplementari di un processo ci sono due funzioni, che
 possono essere usate solo se si hanno i privilegi di amministratore. La prima
@@ -1784,7 +1786,7 @@ delle due 
 \end{functions}
 
 Se invece si vogliono settare i gruppi supplementari del processo a quelli di
-un utente specifico si può usare \func{initgroups} il cui prototipo è:
+un utente specifico, si può usare \func{initgroups} il cui prototipo è:
 \begin{functions}
   \headdecl{sys/types.h}
   \headdecl{grp.h}
@@ -1800,9 +1802,9 @@ un utente specifico si pu
 \end{functions}
 
 La funzione esegue la scansione del database dei gruppi (usualmente
-\file{/etc/groups}) cercando i gruppi di cui è membro \param{user} costruendo
-una lista di gruppi supplementari a cui aggiunge \param{group}, che poi setta
-usando \func{setgroups}.
+\file{/etc/groups}) cercando i gruppi di cui è membro \param{user} e
+costruendo una lista di gruppi supplementari a cui aggiunge \param{group}, che
+poi setta usando \func{setgroups}.
 
 Si tenga presente che sia \func{setgroups} che \func{initgroups} non sono
 definite nello standard POSIX.1 e che pertanto non è possibile utilizzarle
@@ -1817,8 +1819,8 @@ In questa sezione tratteremo pi
 lo \textit{scheduler}\footnote{che è la parte del kernel che si occupa di
   stabilire quale processo dovrà essere posto in esecuzione.} assegna la CPU
 ai vari processi attivi. In particolare prendremo in esame i vari meccanismi
-con cui viene gestita l'assgnazione del tempo di CPU, ed illustreremo le varie
-funzioni di gestione.
+con cui viene gestita l'assegnazione del tempo di CPU, ed illustreremo le
+varie funzioni di gestione.
 
 
 \subsection{I meccanismi di \textit{scheduling}}
@@ -1829,16 +1831,20 @@ il tempo di CPU per l'esecuzione dei processi 
 ed oggetto di numerose ricerche; in ogni caso essa dipende in maniera
 essenziale anche dal tipo di utilizzo che deve essere fatto del sistema.
 
-La cosa è resa ancora più complicata dal fatto che con sistemi
-multi-processore si introduce anche la complessità dovuta alla scelta di quale
-sia la CPU più opportuna da utilizzare.\footnote{nei processori moderni la
-  presenza di ampie cache può rendere poco efficiente trasferire l'esecuzione
-  di un processo da una CPU ad un'altra, per cui occorrono meccanismi per
-  determininare quale è la migliore scelta fra le diverse CPU.} Tutto questo
-comunque appartiene alle sottigliezze dell'implementazione del kernel, e dal
-punto di vista dei programmi che girano in user space di può pensare sempre
-alla risorsa tempo di esecuzione, governata dagli stessi mecca, che nel caso
-di più processori sarà a disposizione di più di un processo alla volta.
+La cosa è resa ancora più complicata dal fatto che con le architetture
+multi-processore si introduce anche la problematica dovuta alla scelta di
+quale sia la CPU più opportuna da utilizzare.\footnote{nei processori moderni
+  la presenza di ampie cache può rendere poco efficiente trasferire
+  l'esecuzione di un processo da una CPU ad un'altra, per cui occorrono
+  meccanismi per determininare quale è la migliore scelta fra le diverse CPU.}
+Tutto questo comunque appartiene alle sottigliezze dell'implementazione del
+kernel, e dal punto di vista dei programmi che girano in user space anche
+quando si hanno più processori, e quindi potenzialmente anche dei processi che
+sono eseguiti davvero in contemporanea, si può pensare alle politiche di
+scheduling come concernenti la risorsa \textsl{tempo di esecuzione}, la cui
+assegnazione sarà governata dagli stessi meccanismi di scelta di priorità,
+solo che nel caso di più processori sarà a disposizione di più di un processo
+alla volta.
 
 Si tenga presente inoltre che l'utilizzo della CPU è soltanto una delle
 risorse (insieme alla memoria e all'accesso alle periferiche) che sono
@@ -1849,8 +1855,8 @@ prestazioni.
 
 La politica tradizionale di scheduling di Unix (che tratteremo in
 \secref{sec:proc_sched_stand}) è sempre stata basata su delle priorità
-dinamiche, che assicurassaro che tutti i processi, anche i meno importanti,
-potessero ricevere un po' di tempo di CPU. 
+dinamiche, che assicurassero che tutti i processi, anche i meno importanti,
+potessero ricevere un po' di tempo di CPU.
 
 Lo standard POSIX però per tenere conto dei sistemi real-time,\footnote{per
   sistema real-time si intende un sistema in grado di eseguire operazioni in
@@ -1859,8 +1865,8 @@ Lo standard POSIX per
   determinabili con certezza assoluta, come nel caso di meccanismi di
   controllo di macchine, dove uno sforamento dei tempi avrebbe conseguenze
   disastrose, e \textit{soft-real-time} in cui un occasionale sforamento è
-  ritenuto accettabile.} in cui è vitale che i processi in che devono essere
-eseguiti in un determinato momento non debbano aspettare la conclusione di un
+  ritenuto accettabile.} in cui è vitale che i processi che devono essere
+eseguiti in un determinato momento non debbano aspettare la conclusione di 
 altri processi che non hanno questa necessità, ha introdotto il concetto di
 \textsl{priorità assoluta}, chimata anche \textsl{priorità statica}, in
 contrapposizione con la normale priorità dinamica.
@@ -1882,7 +1888,6 @@ Questa viene in genere indicata con un numero
 
 
 
-
 \subsection{Il meccanismo di \textit{scheduling} standard}
 \label{sec:proc_sched_stand}
 
@@ -1917,7 +1922,7 @@ abbiamo affrontato la gestione dei processi.
 \label{sec:proc_atom_oper}
 
 La nozione di \textsl{operazione atomica} deriva dal significato greco della
-parola atomo, cioè indivisibile; si dice infatti che unoperazione è atomica
+parola atomo, cioè indivisibile; si dice infatti che un'operazione è atomica
 quando si ha la certezza che, qualora essa venga effettuata, tutti i passaggi
 che devono essere compiuti per realizzarla verranno eseguiti senza possibilità
 di interruzione in una fase intermedia.
@@ -1942,7 +1947,7 @@ processi.
 Nel caso dei segnali invece la situazione è molto più delicata, in quanto lo
 stesso processo, e pure alcune system call, possono essere interrotti in
 qualunque momento, e le operazioni di un eventuale \textit{signal handler}
-sono compiute nello stesso spazio di indirizzi del processo. Per questo anche
+sono compiute nello stesso spazio di indirizzi del processo. Per questo, anche
 il solo accesso o l'assegnazione di una variabile possono non essere più
 operazioni atomiche (torneremo su questi aspetti in \secref{sec:sign_xxx}).
 
@@ -1963,7 +1968,7 @@ condiviso, onde evitare problemi con le ottimizzazioni del codice.
 Si definiscono \textit{race condition} tutte quelle situazioni in cui processi
 diversi operano su una risorsa comune, ed in cui il risultato viene a
 dipendere dall'ordine in cui essi effettuano le loro operazioni. Il caso
-tipico è quello di unoperazione che viene eseguita da un processo in più
+tipico è quello di un'operazione che viene eseguita da un processo in più
 passi, e può essere compromessa dall'intervento di un altro processo che
 accede alla stessa risorsa quando ancora non tutti i passi sono stati
 completati.
@@ -2010,26 +2015,26 @@ eseguire in maniera atomica le operazioni necessarie.
 
 Si dice \textsl{rientrante} una funzione che può essere interrotta in
 qualunque punto della sua esecuzione ed essere chiamata una seconda volta da
-un altro thread di esecuzione senza che questo comporti nessun problema nella
-esecuzione della stessa. La problematica è comune nella programmazione
+un altro thread di esecuzione senza che questo comporti nessun problema
+nell'esecuzione della stessa. La problematica è comune nella programmazione
 multi-thread, ma si hanno gli stessi problemi quando si vogliono chiamare
 delle funzioni all'interno dei manipolatori dei segnali.
 
 Fintanto che una funzione opera soltanto con le variabili locali è rientrante;
-queste infatti vengono tutte le volte allocate nello stack, e un'altra
-invocazione non fa altro che allocarne un'altra copia. Una funzione può non
-essere rientrante quando opera su memoria che non è nello stack.  Ad esempio
-una funzione non è mai rientrante se usa una variabile globale o statica.
-
-Nel caso invece la funzione operi su un oggetto allocato dinamicamente la cosa
-viene a dipendere da come avvengono le operazioni; se l'oggetto è creato ogni
-volta e ritornato indietro la funzione può essere rientrante, se invece esso
-viene individuato dalla funzione stessa due chiamate alla stessa funzione
-potranno interferire quando entrambe faranno riferimento allo stesso oggetto.
-Allo stesso modo una funzione può non essere rientrante se usa e modifica un
-oggetto che le viene fornito dal chiamante: due chiamate possono interferire
-se viene passato lo stesso oggetto; in tutti questi casi occorre molta cura da
-parte del programmatore.
+queste infatti vengono allocate nello stack, e un'altra invocazione non fa
+altro che allocarne un'altra copia. Una funzione può non essere rientrante
+quando opera su memoria che non è nello stack.  Ad esempio una funzione non è
+mai rientrante se usa una variabile globale o statica.
+
+Nel caso invece la funzione operi su un oggetto allocato dinamicamente, la
+cosa viene a dipendere da come avvengono le operazioni: se l'oggetto è creato
+ogni volta e ritornato indietro la funzione può essere rientrante, se invece
+esso viene individuato dalla funzione stessa, due chiamate alla stessa
+funzione potranno interferire quando entrambe faranno riferimento allo stesso
+oggetto.  Allo stesso modo una funzione può non essere rientrante se usa e
+modifica un oggetto che le viene fornito dal chiamante: due chiamate possono
+interferire se viene passato lo stesso oggetto; in tutti questi casi occorre
+molta cura da parte del programmatore.
 
 In genere le funzioni di libreria non sono rientranti, molte di esse ad
 esempio utilizzano variabili statiche, le \acr{glibc} però mettono a
diff --git a/ringraziamenti.tex b/ringraziamenti.tex
new file mode 100644 (file)
index 0000000..2965001
--- /dev/null
@@ -0,0 +1,18 @@
+\chapter{Ringraziamenti}
+\label{cha:ringraziamenti}
+
+Desidero ringraziare tutti coloro che a vario titolo e a più riprese mi hanno
+aiutato ed han contribuito a migliorare in molteplici aspetti la qualità di
+GaPiL. In ordine rigorosamente alfabetico desidero citare:
+\begin{description}
+\item[Alessio Frusciante] per l'apprezzamento, le molteplici correzioni ed i
+  suggerimenti per rendere più chiara l'esposizione.
+\item[Daniele Masini] per la rilettura puntuale, le innumerevoli correzioni, i
+  consigli sull'esposizione ed il contributo relativo alle calling convention
+  dei linguaggi.
+\end{description}
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: