+istruzioni del codice fra padre e figli, nè sull'ordine in cui questi potranno
+essere messi in esecuzione, e 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
+ condition} (vedi \secref{sec:proc_race_cond}.
+
+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 33}) 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).
+
+Un secondo aspetto molto importante nella creazione dei processi figli è
+quello dell'interazione dei vari processi con i file; per illustrarlo meglio
+proviamo a redirigere su un file l'output del nostro programma di test, quello
+che otterremo è:
+
+\footnotesize
+\begin{verbatim}
+[piccardi@selidor sources]$ ./forktest 3 > output
+[piccardi@selidor sources]$ cat output
+Process 1967: forking 3 child
+Child 1 successfully executing
+Child 1, parent 1967, exiting
+Test for forking 3 child
+Spawned 1 child, pid 1968
+Go to next child
+Child 2 successfully executing
+Child 2, parent 1967, exiting
+Test for forking 3 child
+Spawned 1 child, pid 1968
+Go to next child
+Spawned 2 child, pid 1969
+Go to next child
+Child 3 successfully executing
+Child 3, parent 1967, exiting
+Test for forking 3 child
+Spawned 1 child, pid 1968
+Go to next child
+Spawned 2 child, pid 1969
+Go to next child
+Spawned 3 child, pid 1970
+Go to next child
+\end{verbatim}
+\normalsize
+che come si vede è completamente diverso da quanto ottenevamo sul terminale.
+
+Il comportamento delle varie funzioni di interfaccia con i file è analizzato
+in gran dettaglio in \capref{cha:file_unix_interface} e in
+\secref{cha:files_std_interface}. Qui basta accennare che si sono usate le
+funzioni standard della libreria del C che prevedono l'output bufferizzato; e
+questa bufferizzazione (di veda \secref{sec:file_buffering}) varia a seconda
+che si tratti di un file su disco (in cui il buffer viene scaricato su disco
+solo quando necessario) o di un terminale (nel qual caso il buffer viene
+scaricato ad ogni carattere di a capo).
+
+Nel primo esempio allora avevamo che ad ogni chiamata a \func{printf} il
+buffer veniva scaricato, e le singole righe erano stampate a video subito dopo
+l'esecuzione della \func{printf}. Ma con la redirezione su file la scrittura
+non avviene più alla fine di ogni riga e l'output resta nel buffer. Per questo
+motivo, dato che ogni figlio riceve una copia della memoria del padre, esso
+riceverà anche quanto c'è nel buffer delle funzioni di I/O, comprese le linee
+scritte dal padre fino allora. Così quando all'uscita del figlio il buffer
+viene scritto su disco, troveremo nel file anche tutto quello che il processo
+padre aveva scritto prima della sua creazione. E solo alla fine del file,
+dato che in questo caso il padre esce per ultimo, troveremo anche l'output del
+padre.
+
+Ma l'esempio ci mostra un'altro aspetto fondamentale dell'interazione con i
+file, che era valido anche per l'esempio precedente, ma meno evidente; il
+fatto cioè che non solo processi diversi possono scrivere in contemporanea
+sullo stesso file (l'argomento della condivisione dei file in unix è trattato
+in dettaglio in \secref{sec:file_sharing}), ma anche che, a differenza di
+quanto avviene per le variabili, la posizione corrente sul file è condivisa
+fra il padre e tutti i processi figli.
+
+Quello che succede è che quando lo standard output del padre viene rediretto,
+lo stesso avviene anche per tutti i figli; la funzione \func{fork} infatti ha
+la caratteristica di duplicare (allo stesso modo in cui lo fa la funzione
+\func{dup}, trattata in \secref{sec:file_dup}) nei figli tutti i file
+descriptor aperti nel padre, il che comporta che padre e figli condividono le
+stesse voci della \textit{file table} (per la spiegazione di questi termini si
+veda \secref{sec:file_sharing}) e fra cui c'è anche la posizione corrente nel
+file.
+
+In questo modo se un processo scrive sul file aggiornerà la posizione corrente
+sulla \textit{file table}, e tutti gli altri processi, che vedono la stessa
+\textit{file table}, vedranno il nuovo valore. In questo modo si evita, in
+casi come quello appena mostrato in cui diversi processi scrivono sullo stesso
+file, che l'output successivo di un processo vada a sovrapporsi a quello dei
+precedenti: l'output potrà risultare mescolato, ma non ci saranno parti
+perdute per via di una sovrascrittura.
+
+Questo tipo di comportamento è essenziale in tutti quei casi in cui il padre
+crea un figlio e attende la sua conclusione per proseguire, ed entrambi
+scrivono sullo stesso file (un caso tipico è la shell quando lancia un
+programma, il cui output va sullo standard output).
+
+In questo modo, anche se l'output viene rediretto, il padre potrà sempre
+continuare a scrivere in coda a quanto scritto dal figlio in maniera
+automatica; se così non fosse ottenere questo comportamento sarebbe
+estremamente complesso necessitando di una qualche forma di comunicazione fra
+i due processi per far riprendere al padre la scrittura al punto giusto.
+
+In generale comunque non è buona norma far scrivere più processi sullo stesso
+file senza una qualche forma di sincronizzazione in quanto, come visto anche
+con il nostro esempio, le varie scritture risulteranno mescolate fra loro in
+una sequenza impredicibile. Per questo le modalità con cui in genere si usano
+i file dopo una \func{fork} sono sostanzialmente due:
+\begin{enumerate}
+\item Il processo padre aspetta la conclusione del figlio. In questo caso non
+ è necessaria nessuna azione riguardo ai file, in quanto la sincronizzazione
+ della posizione corrente dopo eventuali operazioni di lettura e scrittura
+ effettuate dal figlio è automatica.
+\item L'esecuzione di padre e figlio procede indipendentemente. In questo caso
+ ciascuno dei due processi deve chiudere i file che non gli servono una volta
+ che la \func{fork} è stata eseguita, per evitare ogni forma di interferenza.
+\end{enumerate}
+
+Oltre ai file aperti i processi figli ereditano dal padre una serie di altre
+proprietà; la lista dettagliata delle proprietà che padre e figlio hanno in
+comune dopo l'esecuzione di una \func{fork} è la seguente:
+\begin{itemize*}
+\item i file aperti e gli eventuali flag di \textit{close-on-exec} settati
+ (vedi \secref{sec:proc_exec} e \secref{sec:file_fcntl}).
+\item gli identificatori per il controllo di accesso: il \textit{real user
+ id}, il \textit{real group id}, l'\textit{effective user id},
+ l'\textit{effective group id} ed i \textit{supplementary group id} (vedi
+ \secref{sec:proc_access_id}).
+\item gli identificatori per il controllo di sessione: il \textit{process
+ group id} e il \textit{session id} ed il terminale di controllo (vedi
+ \secref{sec:sess_xxx} e \secref{sec:sess_xxx}).
+\item la directory di lavoro e la directory radice (vedi
+ \secref{sec:file_work_dir} e \secref{sec:file_chroot}).
+\item la maschera dei permessi di creazione (vedi \secref{sec:file_umask}).
+\item la maschera dei segnali bloccati e le azioni installate (vedi
+\secref{sec:sig_xxx}).
+\item i segmenti di memoria condivisa agganciati al processo (vedi
+\secref{sec:ipc_xxx}).
+\item i limiti sulle risorse (vedi \secref{sec:sys_xxx}).
+\item le variabili di ambiente (vedi \secref{sec:proc_environ}).
+\end{itemize*}
+le differenze fra padre e figlio dopo la \func{fork} invece sono:
+\begin{itemize*}
+\item il valore di ritorno di \func{fork}.
+\item il \textit{process id}.
+\item il \textit{parent process id} (quello del figlio viene settato al
+ \acr{pid} del padre).
+\item i valori dei tempi di esecuzione (vedi \secref{sec:sys_xxx}) che
+ nel figlio sono posti a zero.
+\item i \textit{file lock} (vedi \secref{sec:file_locking}), che non
+ vengono ereditati dal figlio.
+\item gli allarmi ed i segnali pendenti (vedi \secref{sec:sig_xxx}), che per il figlio vengono cancellati.
+\end{itemize*}
+
+
+\subsection{La funzione \func{vfork}}
+\label{sec:proc_vfork}
+
+La funzione \func{vfork} è esattamente identica a \func{fork} ed ha la stessa
+semantica e gli stessi errori; la sola differenza è che non viene creata la
+tabella delle pagine né la struttura dei task per il nuovo processo. Il
+processo padre è posto in attesa fintanto che il figlio non ha eseguito una
+\func{execve} o non è uscito con una \func{\_exit}. Il figlio condivide la
+memoria del padre (e modifiche possono avere effetti imprevedibili) e non deve
+ritornare o uscire con \func{exit} ma usare esplicitamente \func{\_exit}.
+
+Questa funzione è un rimasuglio dei vecchi tempi in cui eseguire una
+\func{fork} comportava anche la copia completa del segmento dati del processo
+padre, che costituiva un inutile appesantimento in tutti quei casi in cui la
+\func{fork} veniva fatto solo per poi eseguire una \func{exec}. La funzione
+venne introdotta in BSD per migliorare le prestazioni.
+
+Dato che Linux supporta il \textit{copy on write} la perdita di prestazioni è
+assolutamente trascurabile, e l'uso di questa funzione (che resta un caso
+speciale della funzione \func{clone}), è deprecato; per questo eviteremo di
+trattarla ulteriormente.
+
+
+\subsection{La conclusione di un processo.}
+\label{sec:proc_termination}
+
+In \secref{sec:proc_conclusion} abbiamo già affrontato le modalità con cui
+chiudere un programma, ma dal punto di vista del programma stesso; avendo a
+che fare con un sistema multitasking occorre adesso affrontare l'argomento dal
+punto di vista generale di come il sistema gestisce la conclusione dei
+processi.
+
+Abbiamo già visto in \secref{sec:proc_conclusion} le tre modalità con cui un
+programma viene terminato in maniera normale: la chiamata di \func{exit} (che
+esegue le funzioni registrate per l'uscita e chiude gli stream), il ritorno
+dalla funzione \func{main} (equivalente alla chiamata di \func{exit}), e la
+chiamata ad \func{\_exit} (che passa direttamente alle operazioni di
+terminazione del processo da parte del kernel).
+
+Ma oltre alla conclusione normale abbiamo accennato che esistono anche delle
+modalità di conclusione anomala; queste sono in sostanza due: il programma può
+chiamare la funzione \func{abort} per invocare una chiusura anomala, o essere
+terminato da un segnale. In realtà anche la prima modalità si riconduce alla
+seconda, dato che \func{abort} si limita a generare il segnale
+\macro{SIGABRT}.
+
+Qualunque sia la modalità di conclusione di un processo, il kernel esegue
+comunque una serie di operazioni: chiude tutti i file aperti, rilascia la
+memoria che stava usando, e così via; l'elenco completo delle operazioni
+eseguite alla chiusura di un processo è il seguente:
+\begin{itemize*}
+\item tutti i file descriptor sono chiusi.
+\item viene memorizzato lo stato di terminazione del processo.
+\item ad ogni processo figlio viene assegnato un nuovo padre (in genere
+ \cmd{init}).
+\item viene inviato il segnale \macro{SIGCHLD} al processo padre (vedi
+ \secref{sec:sig_xxx}).
+\item se il processo è un leader di sessione viene mandato un segnale di
+ \macro{SIGHUP} a tutti i processi in background e il terminale di
+ controllo viene disconnesso (vedi \secref{sec:sess_xxx}).
+\item se la conclusione di un processo rende orfano un \textit{process
+ group} ciascun membro del gruppo viene bloccato, e poi gli vengono
+ inviati in successione i segnali \macro{SIGHUP} e \macro{SIGCONT}
+ (vedi \secref{sec:sess_xxx}).
+\end{itemize*}
+ma al di la di queste operazioni è necessario poter disporre di un meccanismo
+ulteriore che consenta di sapere come questa terminazione è avvenuta; dato che
+in 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.
+
+Nel caso di conclusione normale, abbiamo visto in \secref{sec:proc_conclusion}
+che lo stato di uscita del processo viene caratterizzato tramite il valore del
+cosiddetto \textit{exit status}, cioè il valore passato alle funzioni
+\func{exit} o \func{\_exit} (o dal valore di ritorno per \func{main}). Ma se
+il processo viene concluso in maniera anomala il programma non può specificare
+nessun \textit{exit status}, ed è il kernel che deve generare autonomamente il
+\textit{termination status} per indicare le ragioni della conclusione anomala.
+
+Si noti la distinzione fra \textit{exit status} e \textit{termination status}:
+quello che contraddistingue lo stato di chiusura del processo e viene
+riportato attraverso le funzioni \func{wait} o \func{waitpid} (vedi
+\secref{sec:proc_wait}) è sempre quest'ultimo; in caso di conclusione normale
+il kernel usa il primo (nel codice eseguito da \func{\_exit}) per produrre il
+secondo.
+
+La scelta di riportare al padre lo stato di terminazione dei figli, pur
+essendo l'unica possibile, comporta comunque alcune complicazioni: infatti se
+alla sua creazione è scontato che ogni nuovo processo ha un padre, non è detto
+che sia così alla sua conclusione, dato che il padre potrebbe essere già
+terminato (si potrebbe avere cioè quello che si chiama un processo
+\textsl{orfano}).
+
+Questa complicazione viene superata facendo in modo che il processo figlio
+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
+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 \textsl{adottivo}) cui riportare il suo stato
+di terminazione. Come verifica di questo comportamento possiamo eseguire il
+comando \cmd{forktest} imponendo a ciascun processo figlio due
+secondi di attesa prima di uscire, il risultato è:
+
+\footnotesize
+\begin{verbatim}
+[piccardi@selidor sources]$ ./forktest -c2 3
+Process 1972: forking 3 child
+Spawned 1 child, pid 1973
+Child 1 successfully executing
+Go to next child
+Spawned 2 child, pid 1974
+Child 2 successfully executing
+Go to next child
+Child 3 successfully executing
+Spawned 3 child, pid 1975
+Go to next child
+[piccardi@selidor sources]$ Child 3, parent 1, exiting
+Child 2, parent 1, exiting
+Child 1, parent 1, exiting
+\end{verbatim}
+\normalsize
+come si può notare in questo caso il processo padre si conclude prima dei
+figli, tornando alla shell, che stampa il prompt sul terminale: circa due
+secondi dopo viene stampato a video anche l'output dei tre figli che
+terminano, e come si può notare in questo caso, al contrario di quanto visto
+in precedenza, essi riportano 1 come \acr{ppid}.
+
+Altrettanto rilevante è il caso in cui il figlio termina prima del padre,
+perché non è detto che il padre possa ricevere immediatamente lo stato di
+terminazione, quindi il kernel deve comunque conservare una certa quantità di
+informazioni riguardo ai processi che sta terminando.
+
+Questo viene fatto mantenendo attiva la voce nella tabella dei processi, e
+memorizzando alcuni dati essenziali, come il \acr{pid}, i tempi di CPU usati
+dal processo (vedi \secref{sec:sys_unix_time}) e lo stato di
+terminazione\footnote{NdA verificare esattamente cosa c'è!}, mentre la memoria
+in uso ed i file aperti vengono rilasciati immediatamente. I processi che sono
+terminati, ma il cui stato di terminazione non è stato ancora ricevuto dal
+padre sono chiamati \textit{zombie}, essi restano presenti nella tabella dei
+processi ed in genere possono essere identificati dall'output di \cmd{ps} per
+la presenza di una \texttt{Z} nella colonna che ne indica lo stato. Quando il
+padre effettuerà la lettura dello stato di uscita anche questa informazione,
+non più necessaria, verrà scartata e la terminazione potrà dirsi completamente
+conclusa.
+
+Possiamo utilizzare il nostro programma di prova per analizzare anche questa
+condizione: lanciamo il comando \cmd{forktest} in background, indicando al
+processo padre di aspettare 10 secondi prima di uscire; in questo caso, usando
+\cmd{ps} sullo stesso terminale (prima dello scadere dei 10 secondi)
+otterremo:
+
+\footnotesize
+\begin{verbatim}
+[piccardi@selidor sources]$ ps T
+ PID TTY STAT TIME COMMAND
+ 419 pts/0 S 0:00 bash
+ 568 pts/0 S 0:00 ./forktest -e10 3
+ 569 pts/0 Z 0:00 [forktest <defunct>]
+ 570 pts/0 Z 0:00 [forktest <defunct>]
+ 571 pts/0 Z 0:00 [forktest <defunct>]
+ 572 pts/0 R 0:00 ps T
+\end{verbatim} %$
+\normalsize
+e come si vede, dato che non si è fatto nulla per riceverne lo stato di
+terminazione, i tre processi figli sono ancora presenti pur essendosi
+conclusi, con lo stato di zombie e l'indicazione che sono stati terminati.
+
+La possibilità di avere degli zombie deve essere tenuta sempre presente quando
+si scrive un programma che deve essere mantenuto in esecuzione a lungo e
+creare molti figli. In questo caso si deve sempre avere cura di far leggere
+l'eventuale stato di uscita di tutti i figli (in genere questo si fa
+attraverso un apposito \textit{signal handler}, che chiama la funzione
+\func{wait}, vedi \secref{sec:sig_xxx} e \secref{sec:proc_wait}). Questa
+operazione è necessaria perché anche se gli \textit{zombie} non consumano
+risorse di memoria o processore, occupano comunque una voce nella tabella dei
+processi, che a lungo andare potrebbe esaurirsi.
+
+Si noti che quando un processo adottato da \cmd{init} termina, esso non
+diviene uno \textit{zombie}; questo perché una delle funzioni di \cmd{init} è
+appunto quella di chiamare la funzione \func{wait} per i processi cui fa da
+padre, completandone la terminazione. Questo è quanto avviene anche quando,
+come nel caso del precedente esempio con \cmd{forktest}, il padre termina con
+dei figli in stato di zombie: alla sua terminazione infatti tutti i suoi figli
+vengono ereditati (compresi gli zombie) verranno adottati da \cmd{init}, il
+quale provvederà a completarne la terminazione.
+
+Si tenga presente infine che siccome gli zombie sono processi già usciti, non
+c'è modo di eliminarli con il comando \cmd{kill}; l'unica possibilità è quella
+di terminare il processo che li ha generati, in modo che \cmd{init} possa
+adottarli e provvedere a concludere la terminazione.
+
+
+\subsection{Le funzioni \func{wait} e \func{waitpid}}
+\label{sec:proc_wait}