From: Simone Piccardi Date: Thu, 20 Sep 2001 17:13:26 +0000 (+0000) Subject: Iniziate wait & waitpid X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=3d317acde1491cb7fb6f77ef415e010b1c0e6d56;p=gapil.git Iniziate wait & waitpid --- diff --git a/gapil.tex b/gapil.tex index 3109915..7fd9225 100644 --- a/gapil.tex +++ b/gapil.tex @@ -1,4 +1,4 @@ -%% +% %% GaPiL : Guida alla Programmazione in Linux %% %% S. Piccardi Feb. 2001 diff --git a/macro.tex b/macro.tex index dfa9452..64b7656 100644 --- a/macro.tex +++ b/macro.tex @@ -109,7 +109,7 @@ tab.~\thechapter.\theusercount} \par \texttt{ } \end{minipage} \normalsize -\par +\break } % % Wrapper for shell command, functions, filenames, links, diff --git a/prochand.tex b/prochand.tex index 2283fe4..23dd77c 100644 --- a/prochand.tex +++ b/prochand.tex @@ -207,12 +207,11 @@ figlio vedono variabili diverse. La differenza che si ha nei due processi è che nel processo padre il valore di ritorno della funzione fork è il \acr{pid} del processo figlio, mentre nel figlio è zero; in questo modo il programma può identificare se viene eseguito -dal padre o dal figlio. -Si noti come la funzione \func{fork} ritorni \textbf{due} volte: una nel padre -e una nel figlio. La sola differenza che si ha nei due processi è il valore di -ritorno restituito dalla funzione, che nel padre è il \acr{pid} del figlio -mentre nel figlio è zero; in questo modo il programma può identificare se -viene eseguito dal padre o dal figlio. +dal padre o dal figlio. Si noti come la funzione \func{fork} ritorni +\textbf{due} volte: una nel padre e una nel figlio. La sola differenza che si +ha nei due processi è il valore di ritorno restituito dalla funzione, che nel +padre è il \acr{pid} del figlio mentre nel figlio è zero; in questo modo il +programma può identificare se viene eseguito dal padre o dal figlio. La scelta di questi valori non è casuale, un processo infatti può avere più figli, ed il valore di ritorno di \func{fork} è l'unico modo che permette di @@ -648,7 +647,7 @@ lettura dello stato di uscita anche questa informazione, non pi 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 -e10 3 &} in background, +condizione: lanciamo il comando \cmd{forktest -e10 3 \&} 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: @@ -694,16 +693,85 @@ possa adottarli e provvedere a concludere la terminazione. \subsection{Le funzioni \texttt{wait} e \texttt{waitpid}} \label{sec:proc_wait} -Come accennato la funzioni che permettono di leggere lo stato di uscita di un -processo, e di completarne il processo di terminazione sono \func{wait} e -\func{waitpid}, il loro prototipo è: +Abbiamo già visto in precedenza come uno degli usi possibili delle capacità +multitasking di un sistema unix-like consiste nella creazione di programmi di +tipo server, in cui un processo principale attende le richieste che vengono +poi soddisfatte creando una serie di processi figli. Si è gia sottolineato +come in questo caso diventi necessario gestire esplicitamente la conclusione +dei vari processi figli; le funzioni deputate a questo sono sostanzialmente +due, \func{wait} e \func{waitpid}. La prima, il cui prototipo è: \begin{functions} \headdecl{sys/types.h} \headdecl{sys/wait.h} \funcdecl{pid\_t wait(int * status)} -\funcdecl{pid\_t waitpid(pid\_t pid, int *status, int options)} + +Sospende il processo corrente finché un figlio non è uscito, o finché un +segnale termina il processo o chiama una funzione di gestione. Se un figlio è +già uscito la funzione ritorna immediatamente. Al ritorno lo stato di +termininazione del processo viene salvato nella variabile puntata da +\var{status} e tutte le informazioni relative al processo (vedi +\secref{sec:proc_termination}) vengono rilasciate. + +La funzione restituisce il \acr{pid} del figlio in caso di successo e -1 in +caso di errore; \var{errno} può assumere i valori: + \begin{errlist} + \item \macro{EINTR} la funzione è stata interrotta da un segnale. + \end{errlist} +\end{functions} +è presente fin dalle prime versioni di unix; la funzione ritorna alla +conclusione del primo figlio (o immediatamente se un figlio è già uscito), nel +caso un processo abbia più figli il valore di ritorno permette di identificare +qual'è quello che è uscito. + +Questa funzione però ha il difetto di essere poco flessibile, in quanto +ritorna all'uscita di un figlio qualunque, per cui se si vuole attendere la +conclusione di un processo specifico occorre predisporre un meccanismo che +tenga conto dei processi già terminati, e ripeta la chiamata alla funzione nel +caso il processo cercato sia ancora attivo. + +Per questo motivo lo standard Posix.1 ha introdotto \func{waitpid} che +effettua lo stesso servizio, ma dispone di una serie di funzionalità più +ampie; il suo prototipo è: +\begin{functions} +\headdecl{sys/types.h} +\headdecl{sys/wait.h} +\funcdecl{pid\_t waitpid(pid\_t pid, int * status, int options)} + +La funzione restituisce il \acr{pid} del figlio che è uscito, 0 se è stata +specificata l'opzione \macro{WNOHANG} e il figlio non è uscito e -1 per un +errore, nel qual caso \var{errno} assumerà i valori: + \begin{errlist} + \item \macro{EINTR} non è stata specificata l'opzione \macro{WNOHANG} e la + funzione è stata interrotta da un segnale. + \item \macro{ECHILD} il processo specificato da \var{pid} non esiste o non è + figlio del processo chiamante. + \end{errlist} \end{functions} +Le differenze principali fra le due funzioni sono che \func{wait} si blocca +sempre fino a che un figlio non termina, mentre \func{waitpid} ha la +possibilità si specificare un'opzione, \macro{WNOHANG} che ne previene il +blocco, inoltre \func{waitpid} può specificare quale figlio attendere sulla +base del valore soecificato tramite la variabile \var{pid} secondo lo +specchietto riportato in \ntab: +\begin{table}[!htb] + \centering + \begin{tabular}[c]{|c|p{10cm}|} + \hline + \textbf{Valore} & \textbf{Significato}\\ + \hline + \hline + -1 & attende per un figlio qualsiasi, equivalente a \func{wait}\\ + > 0 & \\ + 0 & \\ + < -1& \\ + \hline + \end{tabular} + \caption{Significato del parametro \var{pid} della funzione \func{waitpid}.} + \label{tab:proc_waidpid_pid} +\end{table} + + Come abbiamo appena visto una delle azioni prese dal kernel alla terminazione di un processo è quella di salvarne lo stato e mandare un segnale di