+Si noti inoltre che, come accennato, 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 al loro interno, 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 è:
+\begin{verbatim}
+[piccardi@selidor sources]$ ./forktest 3 > output
+[piccardi@selidor sources]$ cat output
+Test for forking 3 child
+Child 1 successfully executing
+Child 1 exiting
+Test for forking 3 child
+Spawned 1 child, pid 836
+Go to next child
+Child 2 successfully executing
+Child 2 exiting
+Test for forking 3 child
+Spawned 1 child, pid 836
+Go to next child
+Spawned 2 child, pid 837
+Go to next child
+Child 3 successfully executing
+Child 3 exiting
+Test for forking 3 child
+Spawned 1 child, pid 836
+Go to next child
+Spawned 2 child, pid 837
+Go to next child
+Spawned 3 child, pid 838
+Go to next child
+\end{verbatim}
+che come si vede è completamente diverso da quanto ottenevamo sul terminale.
+
+Analizzeremo in gran dettaglio in \capref{cha:file_unix_interface} e in
+\secref{cha:files_std_interface} il comportamento delle varie funzioni di
+interfaccia con i file. Qui basta ricordare che si sono usate le funzioni
+standard della libreria del C che prevedono l'output bufferizzato; e questa
+bufferizzazione 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 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 volta a
+volta. Quando con la redirezione andiamo a scrivere su un file, questo non
+avviene più, e 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 di un figlio il
+buffer viene scritto su disco, troveremo nel file anche tutto quello che il
+processo padre aveva scritto prima della sua creazione. Alla fine, dato che
+in questo caso il padre esce per ultimo, troviamo 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 file table (per la spiegazione di questi termini si veda
+\secref{sec:file_sharing} e referenza a figura da fare) e quindi anche
+l'offset corrente nel file.
+
+In questo modo se un processo scrive sul file aggiornerà l'offset sulla file
+table, e tutti gli altri 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 sovrascrivere
+quello dei precedenti (l'output potrà risultare mescolato, ma non ci saranno
+parti perdute per via di una sovrapposizione).
+
+Questo tipo di comportamento è essenziale in tutti quei casi in cui il padre
+crea un figlio ed attende la sua conclusione per proseguire, ed entrambi
+scrivono sullo stesso file (ad esempio lo standard output). Se l'output viene
+rediretto con questo comportamento avremo che il padre potrà continuare a
+scrivere automaticamente in coda a quanto scritto dal figlio; se così non
+fosse ottenere questo comportamento sarebbe estremamente complesso
+necessitando di una qualche forma di comunicazione fra i due processi.
+
+In generale comunque non è buona norma far scrivere più processi sullo stesso
+file senza una qualche forma di sincronizzazione in quanto, come visto con il
+nostro esempio, le varie scritture risulteranno mescolate fra loro in una
+sequenza impredicibile. Le modalità generali con cui si usano i file dopo una
+\func{fork} sono sostanzialmente due:
+\begin{itemize}
+\item Il processo padre aspetta la conclusione del figlio. In questo caso non
+ è necessaria nessuna azione riguardo ai file, in quanto la sincronizzazione
+ degli offset dopo eventuali operazioni di lettura e scrittura effettuate dal
+ figlio è automatica.
+\item L'esecuzione di padre e figlio procede indipendentemente. In questo caso
+ entrambi devono chiudere i file che non servono, per evitare ogni forma
+\end{itemize}