X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=signal.tex;h=eb939d9e8578d8c1f60a6086f91bdf35f9c32f24;hp=bdb1edb5509541e6d28ebc8b326a7157a11a12d9;hb=0df8310fbad12660d8de351c7550010943a3a167;hpb=e65d03230c2c316ab78f970df9fa42d705c3a925 diff --git a/signal.tex b/signal.tex index bdb1edb..eb939d9 100644 --- a/signal.tex +++ b/signal.tex @@ -1254,15 +1254,106 @@ tempo lo standard POSIX.1 definisce la funzione \func{sleep}, il cui prototipo Pone il processo in stato di sleep per \param{seconds} secondi. - \bodydesc{} + \bodydesc{La funzione restituisce zero se l'attesa viene completata, o il + numero di secondi restanti se viene interrotta da un segnale.} \end{prototype} +La funzione attende per il tempo specificato, a meno di non essere interrotta +da un segnale. In questo caso non è una buona idea ripetere la chiamata per il +tempo rimanente, in quanto la riattivazione del processo può avvenire in un +qualunque momento, ma il valore restituito sarà sempre arrotondato al secondo, +con la conseguenza che, se la successione dei segnali è particolarmente +sfortunata, si potranno avere ritardi anche di parecchi secondi. In genere la +scelta più sicura è quella di stabilire un termine per l'attesa, e ricalcolare +tutte le volte il numero di secondi da aspettare. + +In alcune implementazioni inoltre l'uso di \func{sleep} può avere conflitti +con quello di \macro{SIGALRM}, dato che la funzione può essere realizzata +attraverso \func{pause} e \func{alarm} (in maniera analoga all'esempio che +vedremo fra poco). In tal caso mescolare chiamata di \func{alarm} e +\func{sleep} o modificare l'azione di \macro{SIGALRM}, può causare risultati +indefiniti. Nel caso delle \acr{glibc} è stata usata una implementazione +completamente indipendente e questi problemi non ci sono. + +La granularità di \func{sleep} permette di specificare attese in secondi, per +questo sia sotto BSD4.3 che in SUSv2 è stata definita la funzione +\func{usleep} (dove la \texttt{u} è intesa come sostituzione di $\mu$); i due +standard hanno delle definizioni diverse, ma le \acr{glibc} +seguono\footnote{secondo la man page almeno dalla versione 2.2.2.} seguono +quella di SUSv2 che prevede il seguente prototipo: +\begin{prototype}{unistd.h}{int usleep(unsigned long usec)} + + Pone il processo in stato di sleep per \param{usec} microsecondi. + + \bodydesc{La funzione restituisce zero se l'attesa viene completata, o -1 in + caso di errore, nel qual caso \var{errno} è settata a \macro{EINTR}.} + +\end{prototype} + +Anche questa funzione a seconda delle implementazioni può presentare problemi +nell'interazione con \func{alarm} e \macro{SIGALRM}, ed è pertanto deprecata +in favore di \func{nanosleep}, definita dallo standard POSIX1.b, il cui +prototipo è: +\begin{prototype}{unistd.h}{int nanosleep(const struct timespec *req, struct + timespec *rem)} + + Pone il processo in stato di sleep per il tempo specificato da \param{req}. + In caso di interruzione restituisce il tempo restante in \param{rem}. + + \bodydesc{La funzione restituisce zero se l'attesa viene completata, o -1 in + caso di errore, nel qual caso \var{errno} è settata a + \begin{errlist} + \item[\macro{EINVAL}] si è specificato un numero di secondi negativo o un + numero di nanosecondi maggiore di 999.999.999. + \item[\macro{EINTR}] la funzione è stata interrotta da un segnale. + \end{errlist}} +\end{prototype} + +Lo standard richiede che la funzione sia implementata in maniera del tutto +indipendente da \func{alarm}\footnote{nel caso di Linux questo è fatto + utilizzando direttamente il timer del kernel.} e sia utilizzabile senza +interferenze con l'uso di \macro{SIGALRM}. La funzione prende come parametri +delle strutture di tipo \var{timespec}, la cui definizione è riportata in +\figref{fig:sig_timespec_def}, che permettono di specificare un tempo con una +precisione (teorica) fino al nanosecondo. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} +struct timespec +{ + time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; + \end{lstlisting} + \end{minipage} + \normalsize + \caption{La struttura \var{timespec} di \func{nanosleep}.} + \label{fig:sig_timespec_def} +\end{figure} +La -\subsection{Le semantiche di \macro{SIGCHLD}} + +\subsection{La gestione di \macro{SIGCHLD}} \label{sec:sig_sigchld} +Un semplice esempio per illustrare il funzionamento di un manipolatore di +segnale è quello della gestione di \macro{SIGCHLD}. Abbiamo visto in +\secref{sec:proc_termination} che una delle azioni eseguite dal kernel alla +conclusione di un processo è quella di inviare questo segnale al +padre;\footnote{in realtà in SRV4 eredita la semantica di System V, in cui il + segnale si chiama \macro{SIGCLD} e viene trattato in maniera speciale; se si + setta esplicitamente l'azione a \macro{SIG\_IGN} il segnale non viene + generato ed il sistema non genera zombie (lo stato di terminazione viene + scartato senza dover chiamare una wait), l'azione di default è sempre quella + di ignorare il segnale, ma non attiva questo comportamento. Linux, come BSD + e POSIX, non supporta questa semantica ed usa il nome di \macro{SIGCLD} come + sinonimo di \macro{SIGCHLD}.} è pertanto naturale completare qui la +trattazione della terminazione dei processi illustrando le modalità per +gestire questo segnale. @@ -1270,6 +1361,12 @@ tempo lo standard POSIX.1 definisce la funzione \func{sleep}, il cui prototipo \label{sec:sig_control} +\subsection{Un esempio di problema} +\label{sec:sig_example} + +Come accennato è possibile implementare \func{sleep} a partire da dall'uso di +\func{pause} e \func{alarm}; + \subsection{Le funzioni \func{sigprocmask} e \func{sigpending}}