From: Simone Piccardi Date: Tue, 11 Sep 2001 21:01:09 +0000 (+0000) Subject: Aggiunte minimali X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=351af2e8af7ee3a44410e3837934b45edfe10fc8;ds=sidebyside Aggiunte minimali --- diff --git a/gapil.tex b/gapil.tex index 4ea34f6..3109915 100644 --- a/gapil.tex +++ b/gapil.tex @@ -1,4 +1,4 @@ -%% +%% %% GaPiL : Guida alla Programmazione in Linux %% %% S. Piccardi Feb. 2001 diff --git a/prochand.tex b/prochand.tex index 41d7a34..22da5c0 100644 --- a/prochand.tex +++ b/prochand.tex @@ -282,10 +282,10 @@ Decifrato il numero di figli da creare, il ciclo principale del programma (\texttt{\small 28--40}) esegue in successione la creazione dei processi figli controllando il successo della chiamata a \func{fork} (\texttt{\small 29--31}); ciascun figlio (\texttt{\small 29--31}) si limita a stampare il -suo numero di successione, attendere 2 secondi e scrivere un messaggio prima +suo numero di successione, attendere 3 secondi e scrivere un messaggio prima di uscire. Il processo padre invece (\texttt{\small 29--31}) stampa un messaggio di creazione e procede nell'esecuzione del ciclo. Se eseguiamo il -comando otterremo: +comando otterremo come output sul terminale: \begin{verbatim} [piccardi@selidor sources]$ ./forktest 5 Test for forking 5 child @@ -306,26 +306,33 @@ Child 3 exiting Child 5 exiting \end{verbatim} - Come si vede non si può dire quale processo fra il padre ed il figlio venga eseguito per primo\footnote{anche se nel kernel 2.4.x era stato introdotto un meccanismo che metteva in esecuzione sempre il xxx per primo (TODO recuperare le informazioni esatte)} dopo la chiamata a \func{fork}, nel caso mostrato sopra ad esempio si può notare come dopo la creazione il secondo ed il quinto figlio sia stato stati eseguiti per primi, mantre per gli altri -figli è stato eseguito per primo il padre. In generale l'ordine di esecuzione -dipenderà dalla situazione particolare in si trova la macchina al momento -della chiamata, risultando del tutto impredicibile, per questo motivo se i due -processi devono essere sincronizzati occorrerà ricorrere ad un opportuno -meccanismo di intercomunicazione. - -Si ricordi 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}) saranno effettive -solo per essi, e non hanno alcun effetto sul valore che le stesse variabili -hanno nel processo padre. - - +figli è stato eseguito per primo il padre. + +In generale l'ordine di esecuzione dipenderà, oltre che dall'algoritmo di +scheduling usato dal kernel, dalla particolare situazione in si trova la +macchina al momento della chiamata, risultando del tutto impredicibile. +Eseguendo più volte il programma di prova, si sono ottenute situazioni +completamente diverse, compreso caso in cui il processo padre ha eseguito più +di una \func{fork} prima che uno dei figli venisse messo in +esecuzione. + +Pertanto non si può fare nessuna assunzione sulla sequenza di esecuzione delle +istruzioni del codice fra padre e figli, e se è necessaria una qualche forma +di precedenza occorrerà provvedere ad espliciti meccanismi di +sincronizzazione, pena il rischio di incorrere nelle cosiddette \textit{race + conditions}. + +Si ricordi 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}) saranno effettive solo per essi, e non hanno alcun effetto sul valore +che le stesse variabili hanno nel processo padre. \subsection{Le funzioni \texttt{wait} e \texttt{waitpid}} diff --git a/sources/ForkTest.c b/sources/ForkTest.c index 09035d5..6f73387 100644 --- a/sources/ForkTest.c +++ b/sources/ForkTest.c @@ -26,7 +26,7 @@ * * Usage: forktest -h give all info's * - * $Id: ForkTest.c,v 1.2 2001/09/09 22:45:34 piccardi Exp $ + * $Id: ForkTest.c,v 1.3 2001/09/11 21:01:09 piccardi Exp $ * ****************************************************************/ /* @@ -91,7 +91,7 @@ int main(int argc, char *argv[]) } if (pid == 0) { /* child */ printf("Child %d successfully executing\n", ++i); - sleep(2); + sleep(3); printf("Child %d exiting\n", i); exit(0); } else { /* parent */