From: Simone Piccardi Date: Sun, 6 Sep 2009 14:44:08 +0000 (+0000) Subject: Correzioni varie, in particolare per quanto riguarda i riferimenti a X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=1351fcd88ac4db6a4350bd7c3dfdc7e74ab461aa;p=gapil.git Correzioni varie, in particolare per quanto riguarda i riferimenti a clone. --- diff --git a/fileadv.tex b/fileadv.tex index 1a22108..b4f35d9 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -3278,16 +3278,14 @@ eseguita su un segmento di dimensioni rigorosamente multiple di quelle di una pagina, ed in generale queste potranno non corrispondere alle dimensioni effettive del file o della sezione che si vuole mappare. - \begin{figure}[!htb] \centering - \includegraphics[height=6cm]{img/mmap_boundary} + \includegraphics[height=6.5cm]{img/mmap_boundary} \caption{Schema della mappatura in memoria di una sezione di file di dimensioni non corrispondenti al bordo di una pagina.} \label{fig:file_mmap_boundary} \end{figure} - Il caso più comune è quello illustrato in fig.~\ref{fig:file_mmap_boundary}, in cui la sezione di file non rientra nei confini di una pagina: in tal caso verrà il file sarà mappato su un segmento di memoria che si estende fino al diff --git a/process.tex b/process.tex index 601d3c3..0a5f18d 100644 --- a/process.tex +++ b/process.tex @@ -1400,7 +1400,8 @@ lunghezza del vettore data da un equivalente di \param{argc}, ma la lista terminata da un puntatore nullo. L'indirizzo della lista delle variabili di ambiente è passato attraverso la -variabile globale \var{environ}, a cui si può accedere attraverso una semplice +variabile globale \var{environ}, che viene definita automaticamente per +cisascun processo, e a cui si può accedere attraverso una semplice dichiarazione del tipo: \includecodesnip{listati/env_ptr.c} un esempio della struttura di questa lista, contenente alcune delle variabili @@ -1408,7 +1409,7 @@ pi fig.~\ref{fig:proc_envirno_list}. \begin{figure}[htb] \centering - \includegraphics[width=13cm]{img/environ_var} + \includegraphics[width=14cm]{img/environ_var} \caption{Esempio di lista delle variabili di ambiente.} \label{fig:proc_envirno_list} \end{figure} @@ -1441,8 +1442,12 @@ necessit Gli standard POSIX e XPG3 definiscono alcune di queste variabili (le più comuni), come riportato in tab.~\ref{tab:proc_env_var}. GNU/Linux le supporta -tutte e ne definisce anche altre: per una lista più completa si può -controllare \cmd{man 5 environ}. +tutte e ne definisce anche altre, in particolare poi alcune funzioni di +libreria prevedono la presenza di specifiche variabili di ambiente che ne +modificano il comportamento, come quelle usate per indicare una localizzazione +e quelle per indicare un fuso orario; una lista più completa che comprende +queste ed ulteriori variabili si può ottenere con il comando \cmd{man 7 + environ}. \begin{table}[htb] \centering @@ -1686,7 +1691,7 @@ dette funzioni possono accedere ai loro argomenti. L'accesso viene pertanto realizzato a livello delle librerie standard del C che provvedono gli strumenti adeguati. L'uso di una \textit{variadic function} prevede quindi tre punti: -\begin{itemize} +\begin{itemize*} \item \textsl{Dichiarare} la funzione come \textit{variadic} usando un prototipo che contenga una \textit{ellipsis}. \item \textsl{Definire} la funzione come \textit{variadic} usando la stessa @@ -1694,7 +1699,7 @@ tre punti: gestione di un numero variabile di argomenti. \item \textsl{Invocare} la funzione specificando prima gli argomenti fissi, ed a seguire quelli addizionali. -\end{itemize} +\end{itemize*} Lo standard ISO C prevede che una \index{variadic} \textit{variadic function} abbia sempre almeno un argomento fisso; prima di effettuare la dichiarazione @@ -1724,7 +1729,7 @@ L'unica modalit sequenziale; essi verranno estratti dallo \itindex{stack} \textit{stack} secondo l'ordine in cui sono stati scritti. Per fare questo in \file{stdarg.h} sono definite delle apposite macro; la procedura da seguire è la seguente: -\begin{enumerate} +\begin{enumerate*} \item Inizializzare un puntatore alla lista degli argomenti di tipo \macro{va\_list} attraverso la macro \macro{va\_start}. \item Accedere ai vari argomenti opzionali con chiamate successive alla macro @@ -1732,7 +1737,7 @@ sono definite delle apposite macro; la procedura da seguire il secondo e così via. \item Dichiarare la conclusione dell'estrazione degli argomenti invocando la macro \macro{va\_end}. -\end{enumerate} +\end{enumerate*} In generale è perfettamente legittimo richiedere meno argomenti di quelli che potrebbero essere stati effettivamente forniti, e nella esecuzione delle \macro{va\_arg} ci si può fermare in qualunque momento ed i restanti argomenti @@ -1820,7 +1825,7 @@ Esistono varie modalit immediate è quella di specificare il numero degli argomenti opzionali come uno degli argomenti fissi. Una variazione di questo metodo è l'uso di un argomento per specificare anche il tipo degli argomenti (come fa la stringa di formato -per \func{printf}). +per \func{printf}). Una modalità diversa, che può essere applicata solo quando il tipo degli argomenti lo rende possibile, è quella che prevede di usare un valore speciale diff --git a/prochand.tex b/prochand.tex index f3329a8..c321dd3 100644 --- a/prochand.tex +++ b/prochand.tex @@ -181,11 +181,11 @@ essere posto in esecuzione fino alla successiva invocazione. \subsection{Una panoramica sulle funzioni fondamentali} \label{sec:proc_handling_intro} -In un sistema unix-like i processi vengono sempre creati da altri processi -tramite la funzione \func{fork}; il nuovo processo (che viene chiamato -\textsl{figlio}) creato dalla \func{fork} è una copia identica del processo -processo originale (detto \textsl{padre}), ma ha un nuovo \acr{pid} e viene -eseguito in maniera indipendente (le differenze fra padre e figlio sono +Tradizionalmente in un sistema unix-like i processi vengono sempre creati da +altri processi tramite la funzione \func{fork}; il nuovo processo (che viene +chiamato \textsl{figlio}) creato dalla \func{fork} è una copia identica del +processo processo originale (detto \textsl{padre}), ma ha un nuovo \acr{pid} e +viene eseguito in maniera indipendente (le differenze fra padre e figlio sono affrontate in dettaglio in sez.~\ref{sec:proc_fork}). Se si vuole che il processo padre si fermi fino alla conclusione del processo @@ -308,10 +308,18 @@ affrontato in dettaglio in sez.~\ref{sec:proc_perms}. \label{sec:proc_fork} La funzione \funcd{fork} è la funzione fondamentale della gestione dei -processi: come si è detto l'unico modo di creare un nuovo processo è -attraverso l'uso di questa funzione, essa quindi riveste un ruolo centrale -tutte le volte che si devono scrivere programmi che usano il multitasking. Il -prototipo della funzione è: +processi: come si è detto tradizionalmente l'unico modo di creare un nuovo +processo era attraverso l'uso di questa funzione,\footnote{in realtà oggi la + system call usata più comunemente da Linux per creare nuovi processi è + \func{clone} (vedi \ref{sec:process_clone}) , anche perché a partire dalle + \acr{glibc} 2.3.3 non viene più usata la system call originale, ma la stessa + \func{fork} viene implementata tramite \func{clone}, cosa che consente una + migliore interazione coi \textit{thread}.} essa quindi riveste un ruolo +centrale tutte le volte che si devono scrivere programmi che usano il +multitasking.\footnote{oggi questa rilevanza, con la diffusione dell'uso dei + \textit{thread} che tratteremo al cap.~\ref{cha:threads}, è in parte minore, + ma \func{fork} resta comunque la funzione principale per la creazione di + processi.} Il prototipo della funzione è: \begin{functions} \headdecl{sys/types.h} \headdecl{unistd.h} @@ -596,7 +604,7 @@ 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} +\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 @@ -604,7 +612,7 @@ i file dopo una \func{fork} sono sostanzialmente due: \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} +\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 @@ -622,7 +630,7 @@ comune dopo l'esecuzione di una \func{fork} ed il terminale di controllo (vedi sez.~\ref{sec:sess_proc_group}); \item la directory di lavoro e la directory radice (vedi sez.~\ref{sec:file_work_dir} e sez.~\ref{sec:file_chroot}); -\item la maschera dei permessi di creazione (vedi +\item la maschera dei permessi di creazione dei file (vedi sez.~\ref{sec:file_perm_management}); \item la maschera dei segnali bloccati (vedi sez.~\ref{sec:sig_sigmask}) e le azioni installate (vedi sez.~\ref{sec:sig_gen_beha}); @@ -634,18 +642,34 @@ comune dopo l'esecuzione di una \func{fork} sez.~\ref{sec:proc_real_time} e sez.~\ref{sec:proc_sched_multiprocess}); \item le variabili di ambiente (vedi sez.~\ref{sec:proc_environ}). \end{itemize*} -Le differenze fra padre e figlio dopo la \func{fork} invece sono: +Le differenze fra padre e figlio dopo la \func{fork} invece sono:\footnote{a + parte le ultime quattro, relative a funzionalità specifiche di Linux, le + altre sono esplicitamente menzionate dallo standard POSIX.1-2001.} \begin{itemize*} \item il valore di ritorno di \func{fork}; -\item il \acr{pid} (\textit{process id}); +\item il \acr{pid} (\textit{process id}), assegnato ad un nuovo valore univoco; \item il \acr{ppid} (\textit{parent process id}), quello del figlio viene impostato al \acr{pid} del padre; -\item i valori dei tempi di esecuzione della struttura \struct{tms} (vedi - sez.~\ref{sec:sys_cpu_times}) che nel figlio sono posti a zero; -\item i \textit{lock} sui file (vedi sez.~\ref{sec:file_locking}), che non - vengono ereditati dal figlio; -\item gli allarmi ed i segnali pendenti (vedi sez.~\ref{sec:sig_gen_beha}), che - per il figlio vengono cancellati. +\item i valori dei tempi di esecuzione (vedi sez.~\ref{sec:sys_cpu_times}) e + delle risorse usate (vedi sez.~\ref{sec:sys_resource_use}), che nel figlio + sono posti a zero; +\item i \textit{lock} sui file (vedi sez.~\ref{sec:file_locking}) e sulla + memoria (vedi sez.~\ref{sec:proc_mem_lock}), che non vengono ereditati dal + figlio; +\item gli allarmi (vedi sez.~\ref{sec:sig_alarm_abort}) ed i segnali pendenti + (vedi sez.~\ref{sec:sig_gen_beha}), che per il figlio vengono cancellati. +\item le operazioni di I/O asincrono in corso (vedi + sez.~\ref{sec:file_asyncronous_io}) che non vengono ereditate dal figlio; +\item gli aggiustamenti fatti dal padre ai semafori con \func{semop} (vedi + sez.~\ref{sec:ipc_sysv_sem}). +\item le notifiche sui cambiamenti delle directory con \textit{dnotify} (vedi + sez.~\ref{sec:sig_notification}), che non vengono ereditati dal figlio; +\item le mappature di memoria marcate come \const{MADV\_DONTFORK} (vedi + sez.~\ref{sec:file_memory_map}) che non vengono ereditate dal figlio; +\item l'impostazione con \func{prctl} (vedi sez.~\ref{sec:xxx_prctl}) che + notifica al figlio la terminazione del padre viene cancellata; +\item il segnale di terminazione del figlio è sempre \const{SIGCHLD} anche + qualora nel padre fosse stato modicato (vedi sez.~\ref{sec:process_clone}). \end{itemize*} Una seconda funzione storica usata per la creazione di un nuovo processo è @@ -696,7 +720,7 @@ Qualunque sia la modalit 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} +\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 @@ -711,7 +735,7 @@ eseguite alla chiusura di un processo group} ciascun membro del gruppo viene bloccato, e poi gli vengono inviati in successione i segnali \const{SIGHUP} e \const{SIGCONT} (vedi ancora sez.~\ref{sec:sess_ctrl_term}). -\end{itemize} +\end{itemize*} Oltre queste operazioni è però necessario poter disporre di un meccanismo ulteriore che consenta di sapere come la terminazione è avvenuta: dato che in @@ -948,19 +972,14 @@ sono riportate anche le costanti definite per indicare alcuni di essi. Il comportamento di \func{waitpid} può inoltre essere modificato passando alla funzione delle opportune opzioni tramite l'argomento \param{options}; questo -deve essere specificato come maschera binaria dei flag riportati in -tab.~\ref{tab:proc_waitpid_options},\footnote{oltre a queste in Linux sono - previste del altre opzioni non standard, relative al comportamento con i - \itindex{thread} \textit{thread}, che riprenderemo in - sez.~\ref{sec:thread_xxx}.} che possono essere combinati fra loro con un OR -aritmetico. - -L'uso dell'opzione \const{WNOHANG} consente di prevenire il blocco della -funzione qualora nessun figlio sia uscito (o non si siano verificate le altre -condizioni per l'uscita della funzione); in tal caso la funzione ritornerà un -valore nullo anziché positivo.\footnote{anche in questo caso un valore - positivo indicherà il \acr{pid} del processo di cui si è ricevuto lo stato - ed un valore negativo un errore.} +deve essere specificato come maschera binaria dei flag riportati nella prima +parte in tab.~\ref{tab:proc_waitpid_options} che possono essere combinati fra +loro con un OR aritmetico. Nella seconda parte della stessa tabella si sono +riportati anche alcuni valori non standard specifici di Linux, che consentono +un controllo più dettagliato per i processi creati con la system call generica +\func{clone} (vedi sez.~\ref{sec:process_clone}) usati principalmente per la +gestione della terminazione dei \itindex{thread} \textit{thread} (vedi +sez.~\ref{sec:thread_xxx}). \begin{table}[!htb] \centering @@ -976,6 +995,14 @@ valore nullo anzich \const{WCONTINUED}& Ritorna anche quando un processo figlio che era stato fermato ha ripreso l'esecuzione.\footnotemark \\ \hline + \const{\_\_WCLONE}& Attende solo per i figli creati con \func{clone}, + vale a dire processi che non emettono nessun segnale + o emettono un segnale diverso da \const{SIGCHL} alla + terminazione. \\ + \const{\_\_WALL} & Attende per qualunque processo figlio. \\ + \const{\_\_WNOTHREAD}& Non attende per i figli di altri \textit{thread} + dello stesso gruppo. \\ + \hline \end{tabular} \caption{Costanti che identificano i bit dell'argomento \param{options} della funzione \func{waitpid}.} @@ -984,6 +1011,13 @@ valore nullo anzich \footnotetext{disponibile solo a partire dal kernel 2.6.10.} +L'uso dell'opzione \const{WNOHANG} consente di prevenire il blocco della +funzione qualora nessun figlio sia uscito (o non si siano verificate le altre +condizioni per l'uscita della funzione); in tal caso la funzione ritornerà un +valore nullo anziché positivo.\footnote{anche in questo caso un valore + positivo indicherà il \acr{pid} del processo di cui si è ricevuto lo stato + ed un valore negativo un errore.} + Le altre due opzioni \const{WUNTRACED} e \const{WCONTINUED} consentono rispettivamente di tracciare non la terminazione di un processo, ma il fatto che esso sia stato fermato, o fatto ripartire, e sono utilizzate per la @@ -1032,34 +1066,6 @@ modo, indipendentemente dal fatto \const{SIGCHLD} sia ignorato o meno: attendono la terminazione di un processo figlio e ritornano il relativo \acr{pid} e lo stato di terminazione nell'argomento \param{status}. -In generale in un programma non si vuole essere forzati ad attendere la -conclusione di un processo figlio per proseguire l'esecuzione, specie se tutto -questo serve solo per leggerne lo stato di chiusura (ed evitare eventualmente -la presenza di \index{zombie} \textit{zombie}). Per questo la modalità più -comune di chiamare queste funzioni è quella di utilizzarle all'interno di un -\textit{signal handler} (vedremo un esempio di come gestire \const{SIGCHLD} -con i segnali in sez.~\ref{sec:sig_example}). In questo caso infatti, dato che -il segnale è generato dalla terminazione di un figlio, avremo la certezza che -la chiamata a \func{waitpid} non si bloccherà. - -Come accennato sia \func{wait} che \func{waitpid} restituiscono lo stato di -terminazione del processo tramite il puntatore \param{status} (se non -interessa memorizzare lo stato si può passare un puntatore nullo). Il valore -restituito da entrambe le funzioni dipende dall'implementazione, ma -tradizionalmente alcuni bit (in genere 8) sono riservati per memorizzare lo -stato di uscita, e altri per indicare il segnale che ha causato la -terminazione (in caso di conclusione anomala), uno per indicare se è stato -generato un \itindex{core~dump} \textit{core dump}, ecc.\footnote{le - definizioni esatte si possono trovare in \file{} ma - questo file non deve mai essere usato direttamente, esso viene incluso - attraverso \file{}.} - -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{} ed elencate in tab.~\ref{tab:proc_status_macro} (si tenga -presente che queste macro prendono come parametro la variabile di tipo -\ctyp{int} puntata da \param{status}). - \begin{table}[!htb] \centering \footnotesize @@ -1107,17 +1113,48 @@ presente che queste macro prendono come parametro la variabile di tipo \label{tab:proc_status_macro} \end{table} -\footnotetext[18]{questa macro non è definita dallo standard POSIX.1-2001, ma è +\footnotetext[20]{questa macro non è definita dallo standard POSIX.1-2001, ma è presente come estensione sia in Linux che in altri Unix, deve essere pertanto utilizzata con attenzione (ad esempio è il caso di usarla in un blocco \texttt{\#ifdef WCOREDUMP ... \#endif}.} \footnotetext{è presente solo a partire dal kernel 2.6.10.} +In generale in un programma non si vuole essere forzati ad attendere la +conclusione di un processo figlio per proseguire l'esecuzione, specie se tutto +questo serve solo per leggerne lo stato di chiusura (ed evitare eventualmente +la presenza di \index{zombie} \textit{zombie}). + +Per questo la modalità più comune di chiamare queste funzioni è quella di +utilizzarle all'interno di un \textit{signal handler} (vedremo un esempio di +come gestire \const{SIGCHLD} con i segnali in sez.~\ref{sec:sig_example}). In +questo caso infatti, dato che il segnale è generato dalla terminazione di un +figlio, avremo la certezza che la chiamata a \func{waitpid} non si bloccherà. + +Come accennato sia \func{wait} che \func{waitpid} restituiscono lo stato di +terminazione del processo tramite il puntatore \param{status} (se non +interessa memorizzare lo stato si può passare un puntatore nullo). Il valore +restituito da entrambe le funzioni dipende dall'implementazione, ma +tradizionalmente alcuni bit (in genere 8) sono riservati per memorizzare lo +stato di uscita, e altri per indicare il segnale che ha causato la +terminazione (in caso di conclusione anomala), uno per indicare se è stato +generato un \itindex{core~dump} \textit{core dump}, ecc.\footnote{le + definizioni esatte si possono trovare in \file{} ma + questo file non deve mai essere usato direttamente, esso viene incluso + attraverso \file{}.} + +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{} ed elencate in tab.~\ref{tab:proc_status_macro}; si tenga +presente che queste macro prevedono che gli si passi come parametro la +variabile di tipo \ctyp{int} puntata dall'argomento \param{status} restituito +da \func{wait} o \func{waitpid}. + Si tenga conto che nel caso di conclusione anomala il valore restituito da -\val{WTERMSIG} può essere confrontato con le costanti definite in -\file{signal.h} ed elencate in tab.~\ref{tab:sig_signal_list}, e stampato -usando le apposite funzioni trattate in sez.~\ref{sec:sig_strsignal}. +\val{WTERMSIG} può essere confrontato con le costanti che identificano i +segnali definite in \file{signal.h} ed elencate in +tab.~\ref{tab:sig_signal_list}, e stampato usando le apposite funzioni +trattate in sez.~\ref{sec:sig_strsignal}. A partire dal kernel 2.6.9, sempre in conformità allo standard POSIX.1-2001, è stata introdotta una nuova funzione di attesa che consente di avere un @@ -1147,13 +1184,12 @@ suo prototipo \end{functions} La funzione prevede che si specifichi quali processi si intendono osservare -usando i due argomenti \param{idtype} ed \param{id}; il primo indica se si -vuole porsi in attesa su un singolo processo, un gruppo di processi o un +usando i due argomenti \param{idtype} ed \param{id}; il primo indica se ci si +vuole porre in attesa su un singolo processo, un gruppo di processi o un processo qualsiasi, e deve essere specificato secondo uno dei valori di tab.~\ref{tab:proc_waitid_idtype}; il secondo indica, a seconda del valore del primo, quale processo o quale gruppo di processi selezionare. - \begin{table}[!htb] \centering \footnotesize diff --git a/signal.tex b/signal.tex index 7773028..5ea24ce 100644 --- a/signal.tex +++ b/signal.tex @@ -1078,7 +1078,7 @@ escludere alcuni processi specifici: nel caso in questione Linux non invia il segnale al processo che ha effettuato la chiamata. -\subsection{Le funzioni \func{alarm} e \func{abort}} +\subsection{Le funzioni \func{alarm}, \func{abort} ed i \textit{timer}} \label{sec:sig_alarm_abort} Un caso particolare di segnali generati a richiesta è quello che riguarda i @@ -1252,7 +1252,7 @@ valore corrente di un timer senza modificarlo, Legge in \param{value} il valore del timer specificato da \param{which}. \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di - errore e restituisce gli stessi errori di \func{getitimer}} + errore e restituisce gli stessi errori di \func{getitimer}.} \end{prototype} \noindent i cui argomenti hanno lo stesso significato e formato di quelli di \func{setitimer}.