Alcune correzioni ai font dei link, e una trattazione esplicita
[gapil.git] / prochand.tex
index 94d316eca7ec189ffb5bc8a5455a1fca12e9fd92..3522bbb2a2ae78f252a3516711b28ff3d41885ff 100644 (file)
@@ -194,9 +194,9 @@ abbastanza limitata sulle cause della terminazione del processo figlio.
 Quando un processo ha concluso il suo compito o ha incontrato un errore non
 risolvibile esso può essere terminato con la funzione \func{exit} (si veda
 quanto discusso in sez.~\ref{sec:proc_conclusion}). La vita del processo però
 Quando un processo ha concluso il suo compito o ha incontrato un errore non
 risolvibile esso può essere terminato con la funzione \func{exit} (si veda
 quanto discusso in sez.~\ref{sec:proc_conclusion}). La vita del processo però
-termina solo quando la notifica della sua conclusione viene ricevuta dal
-processo padre, a quel punto tutte le risorse allocate nel sistema ad esso
-associate vengono rilasciate.
+termina completamente solo quando la notifica della sua conclusione viene
+ricevuta dal processo padre, a quel punto tutte le risorse allocate nel
+sistema ad esso associate vengono rilasciate.
 
 Avere due processi che eseguono esattamente lo stesso codice non è molto
 utile, normalmente si genera un secondo processo per affidargli l'esecuzione
 
 Avere due processi che eseguono esattamente lo stesso codice non è molto
 utile, normalmente si genera un secondo processo per affidargli l'esecuzione
@@ -431,7 +431,6 @@ Se eseguiamo il comando\footnote{che 
 senza specificare attese (come si può notare in (\texttt{\small 17--19}) i
 valori predefiniti specificano di non attendere), otterremo come output sul
 terminale:
 senza specificare attese (come si può notare in (\texttt{\small 17--19}) i
 valori predefiniti specificano di non attendere), otterremo come output sul
 terminale:
-
 \footnotesize
 \begin{verbatim}
 [piccardi@selidor sources]$ export LD_LIBRARY_PATH=./; ./forktest 3
 \footnotesize
 \begin{verbatim}
 [piccardi@selidor sources]$ export LD_LIBRARY_PATH=./; ./forktest 3
@@ -452,17 +451,14 @@ Go to next child
 \normalsize
 
 Esaminiamo questo risultato: una prima conclusione che si può trarre è che non
 \normalsize
 
 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
-  \itindex{scheduler} \textit{scheduler} di Ingo Molnar che esegue sempre per
-  primo il figlio; per mantenere la portabilità è opportuno non fare comunque
-  affidamento su questo comportamento.} dopo la chiamata a \func{fork};
-dall'esempio si può notare infatti come nei primi due cicli sia stato eseguito
-per primo il padre (con la stampa del \acr{pid} del nuovo processo) per poi
-passare all'esecuzione del figlio (completata con i due avvisi di esecuzione
-ed uscita), e tornare all'esecuzione del padre (con la stampa del passaggio al
-ciclo successivo), mentre la terza volta è stato prima eseguito il figlio
-(fino alla conclusione) e poi il padre.
+si può dire quale processo fra il padre ed il figlio venga eseguito per primo
+dopo la chiamata a \func{fork}; dall'esempio si può notare infatti come nei
+primi due cicli sia stato eseguito per primo il padre (con la stampa del
+\acr{pid} del nuovo processo) per poi passare all'esecuzione del figlio
+(completata con i due avvisi di esecuzione ed uscita), e tornare
+all'esecuzione del padre (con la stampa del passaggio al ciclo successivo),
+mentre la terza volta è stato prima eseguito il figlio (fino alla conclusione)
+e poi il padre.
 
 In generale l'ordine di esecuzione dipenderà, oltre che dall'algoritmo di
 \itindex{scheduler} scheduling usato dal kernel, dalla particolare situazione
 
 In generale l'ordine di esecuzione dipenderà, oltre che dall'algoritmo di
 \itindex{scheduler} scheduling usato dal kernel, dalla particolare situazione
@@ -479,6 +475,24 @@ occorrer
 rischio di incorrere nelle cosiddette \itindex{race~condition} \textit{race
   condition} (vedi sez.~\ref{sec:proc_race_cond}).
 
 rischio di incorrere nelle cosiddette \itindex{race~condition} \textit{race
   condition} (vedi sez.~\ref{sec:proc_race_cond}).
 
+In realtà a partire dal kernel 2.5.2-pre10 il nuovo \itindex{scheduler}
+\textit{scheduler} di Ingo Molnar esegue sempre per primo il
+figlio;\footnote{i risultati precedenti sono stati ottenuti su un kernel della
+  serie 2.4.}  questa è una ottimizzazione che serve a evitare che il padre,
+effettuando per primo una operazione di scrittura in memoria, attivi il
+meccanismo del \itindex{copy~on~write} \textit{copy on write}. Questa
+operazione infatti potrebbe risultare del tutto inutile qualora il figlio
+fosse stato creato solo per eseguire una \func{exec}, in tal caso infatti si
+invocherebbe un'altro proramma scartando completamente lo spazio degli
+indirizzi, rendendo superflua la copia della memoria modificata dal padre.
+
+Eseguendo sempre per primo il figlio la \func{exec} verrebbe effettuata subito
+avendo così la certezza che il \itindex{copy~on~write} \textit{copy on write}
+viene utilizzato solo quando necessario. Quanto detto in precedenza vale
+allora soltanto per i kernel fino al 2.4, per mantenere la portabilità è però
+opportuno non fare affidamento su questo comportamento, che non si riscontra
+in altri Unix e nelle versioni del kernel precendenti a quella indicata.
+
 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
 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
@@ -490,7 +504,6 @@ 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 è:
 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
 \footnotesize
 \begin{verbatim}
 [piccardi@selidor sources]$ ./forktest 3 > output
@@ -538,7 +551,7 @@ ogni figlio riceve una copia della memoria del padre, esso ricever
 quanto c'è nel buffer delle funzioni di I/O, comprese le linee scritte dal
 padre fino allora. Così quando il buffer viene scritto su disco all'uscita del
 figlio, troveremo nel file anche tutto quello che il processo padre aveva
 quanto c'è nel buffer delle funzioni di I/O, comprese le linee scritte dal
 padre fino allora. Così quando il buffer viene scritto su disco all'uscita del
 figlio, troveremo nel file anche tutto quello che il processo padre aveva
-scritto prima della sua creazione.  E alla fine del file (dato che in questo
+scritto prima della sua creazione. E alla fine del file (dato che in questo
 caso il padre esce per ultimo) troveremo anche l'output completo del padre.
 
 L'esempio ci mostra un altro aspetto fondamentale dell'interazione con i file,
 caso il padre esce per ultimo) troveremo anche l'output completo del padre.
 
 L'esempio ci mostra un altro aspetto fondamentale dell'interazione con i file,
@@ -727,6 +740,8 @@ che sia cos
 terminato (si potrebbe avere cioè quello che si chiama un processo
 \textsl{orfano}). 
 
 terminato (si potrebbe avere cioè quello che si chiama un processo
 \textsl{orfano}). 
 
+% TODO verificare il reparenting
+
 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
 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
@@ -736,7 +751,6 @@ avr
 cui riportare il suo stato di terminazione.  Come verifica di questo
 comportamento possiamo eseguire il nostro programma \cmd{forktest} imponendo a
 ciascun processo figlio due secondi di attesa prima di uscire, il risultato è:
 cui riportare il suo stato di terminazione.  Come verifica di questo
 comportamento possiamo eseguire il nostro programma \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
 \footnotesize
 \begin{verbatim}
 [piccardi@selidor sources]$ ./forktest -c2 3
@@ -1227,7 +1241,8 @@ ritorno di \func{waitid} verranno avvalorati i seguenti campi:
   \const{CLD\_STOPPED}, \const{CLD\_CONTINUED} (vedi tab.~\ref{xxx_si_code}).
 \end{basedescript}
 
   \const{CLD\_STOPPED}, \const{CLD\_CONTINUED} (vedi tab.~\ref{xxx_si_code}).
 \end{basedescript}
 
-%TODO mettere riferimento alla tabella giusta
+%TODO mettere riferimento alla tabella giusta (vedere man credentials e man
+%     waitid)
 
 Infine Linux, seguendo un'estensione di BSD, supporta altre due funzioni per
 la lettura dello stato di terminazione di un processo, analoghe alle
 
 Infine Linux, seguendo un'estensione di BSD, supporta altre due funzioni per
 la lettura dello stato di terminazione di un processo, analoghe alle
@@ -1256,7 +1271,7 @@ utilizzata anche dalla funzione \func{getrusage} (vedi
 sez.~\ref{sec:sys_resource_use}) per ottenere le risorse di sistema usate da un
 processo; la sua definizione è riportata in fig.~\ref{fig:sys_rusage_struct}.
 
 sez.~\ref{sec:sys_resource_use}) per ottenere le risorse di sistema usate da un
 processo; la sua definizione è riportata in fig.~\ref{fig:sys_rusage_struct}.
 
-\subsection{Le funzioni \func{exec}}
+\subsection{La funzione \func{exec} e le funzioni di esecuzione dei programmi}
 \label{sec:proc_exec}
 
 Abbiamo già detto che una delle modalità principali con cui si utilizzano i
 \label{sec:proc_exec}
 
 Abbiamo già detto che una delle modalità principali con cui si utilizzano i
@@ -1489,7 +1504,7 @@ chiamato come se si fosse eseguito il comando \cmd{interpreter [argomenti]
   lunga restituisce un errore di \const{ENAMETOOLONG}, una comparazione dei
   vari comportamenti si trova su
   \href{http://www.in-ulm.de/~mascheck/various/shebang/}
   lunga restituisce un errore di \const{ENAMETOOLONG}, una comparazione dei
   vari comportamenti si trova su
   \href{http://www.in-ulm.de/~mascheck/various/shebang/}
-  {\texttt{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.}
+  {\textsf{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.}
 
 Con la famiglia delle \func{exec} si chiude il novero delle funzioni su cui è
 basata la gestione dei processi in Unix: con \func{fork} si crea un nuovo
 
 Con la famiglia delle \func{exec} si chiude il novero delle funzioni su cui è
 basata la gestione dei processi in Unix: con \func{fork} si crea un nuovo
@@ -2116,7 +2131,7 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.23;
   benché l'infrastruttura per crearla sia presente (vedi anche
   sez.~\ref{sec:file_xattr}) finora non è disponibile nessuna realizzazione
   delle specifiche POSIX.1e, esistono però dei patch di sicurezza del kernel,
   benché l'infrastruttura per crearla sia presente (vedi anche
   sez.~\ref{sec:file_xattr}) finora non è disponibile nessuna realizzazione
   delle specifiche POSIX.1e, esistono però dei patch di sicurezza del kernel,
-  come LIDS (vedi \href{http://www.lids.org}{\texttt{http://www.lids.org/})}
+  come LIDS (vedi \href{http://www.lids.org}{\textsf{http://www.lids.org/})}
   che realizzano qualcosa di simile.}
 
 
   che realizzano qualcosa di simile.}
 
 
@@ -3097,7 +3112,7 @@ tocca al kernel decidere quale deve essere eseguito.  Il meccanismo con cui
 vengono gestiti questi processi dipende dalla politica di scheduling che si è
 scelta; lo standard ne prevede due:
 \begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
 vengono gestiti questi processi dipende dalla politica di scheduling che si è
 scelta; lo standard ne prevede due:
 \begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
-\item[\textit{FIFO}] \textit{First In First Out}. Il processo viene eseguito
+\item[\textsf{FIFO}] \textit{First In First Out}. Il processo viene eseguito
   fintanto che non cede volontariamente la CPU (con \func{sched\_yield}), si
   blocca, finisce o viene interrotto da un processo a priorità più alta. Se il
   processo viene interrotto da uno a priorità più alta esso resterà in cima
   fintanto che non cede volontariamente la CPU (con \func{sched\_yield}), si
   blocca, finisce o viene interrotto da un processo a priorità più alta. Se il
   processo viene interrotto da uno a priorità più alta esso resterà in cima
@@ -3105,7 +3120,7 @@ scelta; lo standard ne prevede due:
   più alta diverranno inattivi. Se invece lo si blocca volontariamente sarà
   posto in coda alla lista (ed altri processi con la stessa priorità potranno
   essere eseguiti).
   più alta diverranno inattivi. Se invece lo si blocca volontariamente sarà
   posto in coda alla lista (ed altri processi con la stessa priorità potranno
   essere eseguiti).
-\item[\textit{RR}] \textit{Round Robin}. Il comportamento è del tutto analogo
+\item[\textsf{RR}] \textit{Round Robin}. Il comportamento è del tutto analogo
   a quello precedente, con la sola differenza che ciascun processo viene
   eseguito al massimo per un certo periodo di tempo (la cosiddetta
   \textit{time slice}) dopo di che viene automaticamente posto in fondo alla
   a quello precedente, con la sola differenza che ciascun processo viene
   eseguito al massimo per un certo periodo di tempo (la cosiddetta
   \textit{time slice}) dopo di che viene automaticamente posto in fondo alla