+\fdesc{Predispone l'invio di un segnale di allarme.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori \errval{EINVAL} o \errval{EFAULT}
+ nel loro significato generico.}
+\end{funcproto}
+
+
+La funzione predispone l'invio di un segnale di allarme alla scadenza
+dell'intervallo indicato dall'argomento \param{value}. Il valore
+dell'argomento \param{which} permette di specificare quale dei tre timer
+illustrati in precedenza usare; i possibili valori sono riportati in
+tab.~\ref{tab:sig_setitimer_values}.
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Valore} & \textbf{Timer} \\
+ \hline
+ \hline
+ \constd{ITIMER\_REAL} & \textit{real-time timer}\\
+ \constd{ITIMER\_VIRTUAL} & \textit{virtual timer}\\
+ \constd{ITIMER\_PROF} & \textit{profiling timer}\\
+ \hline
+ \end{tabular}
+ \caption{Valori dell'argomento \param{which} per la funzione
+ \func{setitimer}.}
+ \label{tab:sig_setitimer_values}
+\end{table}
+
+Il valore della struttura specificata \param{value} viene usato per impostare
+il timer, se il puntatore \param{ovalue} non è nullo il precedente valore
+viene salvato qui. I valori dei timer devono essere indicati attraverso una
+struttura \struct{itimerval}, definita in fig.~\ref{fig:file_stat_struct}.
+
+La struttura è composta da due membri, il primo, \var{it\_interval} definisce
+il periodo del timer; il secondo, \var{it\_value} il tempo mancante alla
+scadenza. Entrambi esprimono i tempi tramite una struttura \struct{timeval} che
+permette una precisione fino al microsecondo.
+
+Ciascun timer decrementa il valore di \var{it\_value} fino a zero, poi invia
+il segnale e reimposta \var{it\_value} al valore di \var{it\_interval}, in
+questo modo il ciclo verrà ripetuto; se invece il valore di \var{it\_interval}
+è nullo il timer si ferma.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.8\textwidth}
+ \includestruct{listati/itimerval.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{itimerval}, che definisce i valori dei timer
+ di sistema.}
+ \label{fig:sig_itimerval}
+\end{figure}
+
+L'uso di \func{setitimer} consente dunque un controllo completo di tutte le
+caratteristiche dei timer, ed in effetti la stessa \func{alarm}, benché
+definita direttamente nello standard POSIX.1, può a sua volta essere espressa
+in termini di \func{setitimer}, come evidenziato dal manuale della \acr{glibc}
+\cite{GlibcMan} che ne riporta la definizione mostrata in
+fig.~\ref{fig:sig_alarm_def}.\footnote{questo comporta anche che non è il caso
+ di mescolare chiamate ad \func{abort} e a \func{setitimer}.}
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.8\textwidth}
+ \includestruct{listati/alarm_def.c}
+ \end{minipage}
+ \normalsize
+ \caption{Definizione di \func{alarm} in termini di \func{setitimer}.}
+ \label{fig:sig_alarm_def}
+\end{figure}
+
+Si deve comunque tenere presente che fino al kernel 2.6.16 la precisione di
+queste funzioni era limitata dalla frequenza del timer di sistema, determinato
+dal valore della costante \texttt{HZ} di cui abbiamo già parlato in
+sez.~\ref{sec:proc_hierarchy}, in quanto le temporizzazioni erano calcolate in
+numero di interruzioni del timer (i cosiddetti ``\textit{jiffies}''), ed era
+assicurato soltanto che il segnale non sarebbe stato mai generato prima della
+scadenza programmata (l'arrotondamento cioè era effettuato per
+eccesso).\footnote{questo in realtà non è del tutto vero a causa di un bug,
+ presente fino al kernel 2.6.12, che in certe circostanze causava l'emissione
+ del segnale con un arrotondamento per difetto.}
+
+L'uso del contatore dei \textit{jiffies}, un intero a 32 bit nella maggior
+parte dei casi, comportava inoltre l'impossibilità di specificare tempi molto
+lunghi. superiori al valore della costante \constd{MAX\_SEC\_IN\_JIFFIES},
+pari, nel caso di default di un valore di \const{HZ} di 250, a circa 99 giorni
+e mezzo. Con il cambiamento della rappresentazione effettuato nel kernel
+2.6.16 questo problema è scomparso e con l'introduzione dei timer ad alta
+risoluzione (vedi sez.~\ref{sec:sig_timer_adv}) nel kernel 2.6.21 la
+precisione è diventata quella fornita dall'hardware disponibile.
+
+Una seconda causa di potenziali ritardi è che il segnale viene generato alla
+scadenza del timer, ma poi deve essere consegnato al processo; se quest'ultimo
+è attivo (questo è sempre vero per \const{ITIMER\_VIRTUAL}) la consegna è
+immediata, altrimenti può esserci un ulteriore ritardo che può variare a
+seconda del carico del sistema.
+
+Questo ha una conseguenza che può indurre ad errori molto subdoli, si tenga
+conto poi che in caso di sistema molto carico, si può avere il caso patologico
+in cui un timer scade prima che il segnale di una precedente scadenza sia
+stato consegnato. In questo caso, per il comportamento dei segnali descritto
+in sez.~\ref{sec:sig_sigchld}, un solo segnale sarà consegnato. Per questo
+oggi l'uso di questa funzione è deprecato a favore degli
+\textit{high-resolution timer} e della cosiddetta \textit{POSIX Timer API},
+che tratteremo in sez.~\ref{sec:sig_timer_adv}.
+
+Dato che sia \func{alarm} che \func{setitimer} non consentono di leggere il
+valore corrente di un timer senza modificarlo, è possibile usare la funzione
+\funcd{getitimer}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/time.h}
+\fdecl{int getitimer(int which, struct itimerval *value)}
+\fdesc{Legge il valore di un timer.}
+}
+
+{ La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà gli stessi valori di \func{getitimer}. }
+\end{funcproto}
+
+La funzione legge nella struttura \struct{itimerval} puntata da \param{value}
+il valore del timer specificato da \param{which} ed i suoi argomenti hanno lo
+stesso significato e formato di quelli di \func{setitimer}.
+
+
+\subsection{Le funzioni di pausa e attesa}
+\label{sec:sig_pause_sleep}
+
+Sono parecchie le occasioni in cui si può avere necessità di sospendere
+temporaneamente l'esecuzione di un processo. Nei sistemi più elementari in
+genere questo veniva fatto con un ciclo di attesa in cui il programma ripete
+una operazione un numero sufficiente di volte per far passare il tempo
+richiesto.
+
+Ma in un sistema multitasking un ciclo di attesa è solo un inutile spreco di
+tempo di processore dato che altri programmi possono essere eseguiti nel
+frattempo, per questo ci sono delle apposite funzioni che permettono di
+mantenere un processo in attesa per il tempo voluto, senza impegnare il
+processore. In pratica si tratta di funzioni che permettono di portare
+esplicitamente il processo nello stato di \textit{sleep} (si ricordi quanto
+illustrato in tab.~\ref{tab:proc_proc_states}) per un certo periodo di tempo.
+
+La prima di queste è la funzione di sistema \funcd{pause}, che viene usata per
+mettere un processo in attesa per un periodo di tempo indefinito, fino
+all'arrivo di un segnale, il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int pause(void)}
+\fdesc{Pone il processo in pausa fino al ricevimento di un segnale.}
+}
+
+{La funzione ritorna solo dopo che un segnale è stato ricevuto ed il relativo
+ gestore è ritornato, nel qual caso restituisce $-1$ e \var{errno} assume il
+ valore \errval{EINTR}.}
+\end{funcproto}
+
+La funzione ritorna sempre con una condizione di errore, dato che il successo
+sarebbe quello di continuare ad aspettare indefinitamente. In genere si usa
+questa funzione quando si vuole mettere un processo in attesa di un qualche
+evento specifico che non è sotto il suo diretto controllo, ad esempio la si
+può usare per interrompere l'esecuzione del processo fino all'arrivo di un
+segnale inviato da un altro processo.
+
+Quando invece si vuole fare attendere un processo per un intervallo di tempo
+già noto in partenza, lo standard POSIX.1 prevede una funzione di attesa
+specifica, \funcd{sleep}, il cui prototipo è:
+
+\begin{funcproto}{
+
+\fhead{unistd.h}
+\fdecl{unsigned int sleep(unsigned int seconds)}
+\fdesc{Pone il processo in pausa per un tempo in secondi.}
+}
+
+{La funzione ritorna $0$ se l'attesa viene completata o il
+ numero di secondi restanti se viene interrotta da un segnale, non sono
+ previsti codici di errore.}
+\end{funcproto}
+
+La funzione pone il processo in stato di \textit{sleep} per il numero di
+secondi specificato dall'argomento \param{seconds}, a meno di non essere
+interrotta da un segnale. Alla terminazione del periodo di tempo indicato la
+funzione ritorna riportando il processo in stato \textit{runnable} così che
+questo possa riprendere l'esecuzione.
+
+In caso di interruzione della funzione non è una buona idea ripetere la
+chiamata per il tempo rimanente restituito dalla stessa, in quanto la
+riattivazione del processo può avvenire in un qualunque momento, ma il valore
+restituito sarà sempre arrotondato al secondo. Questo può avere la conseguenza
+che se la successione dei segnali è particolarmente sfortunata e le differenze
+si accumulano, si possono avere ritardi anche di parecchi secondi rispetto a
+quanto programmato inizialmente. In genere la scelta più sicura in questo caso
+è quella di stabilire un termine per l'attesa, e ricalcolare tutte le volte il
+numero di secondi che restano da aspettare.
+
+Si tenga presente che alcune implementazioni l'uso di \func{sleep} può avere
+conflitti con quello di \signal{SIGALRM}, dato che la funzione può essere
+realizzata con l'uso di \func{pause} e \func{alarm}, in una maniera analoga a
+quella dell'esempio che vedremo in sez.~\ref{sec:sig_example}. In tal caso
+mescolare chiamate di \func{alarm} e \func{sleep} o modificare l'azione
+associata \signal{SIGALRM}, può portare a dei risultati indefiniti. Nel caso
+della \acr{glibc} è stata usata una implementazione completamente indipendente
+e questi problemi non ci sono, ma un programma portabile non può fare questa
+assunzione.
+
+La granularità di \func{sleep} permette di specificare attese soltanto in
+secondi, per questo sia sotto BSD4.3 che in SUSv2 è stata definita un'altra
+funzione con una precisione teorica del microsecondo. I due standard hanno
+delle definizioni diverse, ma la \acr{glibc} segue (secondo la pagina di
+manuale almeno dalla versione 2.2.2) quella di SUSv2 per cui la
+funzione \funcd{usleep} (dove la \texttt{u} è intesa come sostituzione di
+$\mu$), ha il seguente prototipo:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int usleep(unsigned long usec)}
+\fdesc{Pone il processo in pausa per un tempo in microsecondi.}
+}
+
+{La funzione ritorna $0$ se l'attesa viene completata e $-1$ per un errore,
+ nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+ \item[\errcode{EINVAL}] si è indicato un valore di \param{usec} maggiore di
+ 1000000.
+ \end{errlist}
+}
+\end{funcproto}
+
+Anche questa funzione, a seconda delle implementazioni, può presentare
+problemi nell'interazione con \func{alarm} e \signal{SIGALRM}, per questo
+motivo, pur essendovi citata, nello standard POSIX.1-2001 viene deprecata in
+favore della nuova funzione di sistema \funcd{nanosleep}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int nanosleep(const struct timespec *req, struct timespec *rem)}
+\fdesc{Pone il processo in pausa per un intervallo di tempo.}
+}
+
+{La funzione ritorna $0$ se l'attesa viene completata e $-1$ per un errore,
+ nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+ \item[\errcode{EINVAL}] si è specificato un numero di secondi negativo o un
+ numero di nanosecondi maggiore di 999.999.999.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione pone il processo in pausa portandolo nello stato di \textit{sleep}
+per il tempo specificato dall'argomento \param{req}, ed in caso di
+interruzione restituisce il tempo restante nell'argomento \param{rem}. Lo
+standard richiede che la funzione sia implementata in maniera del tutto
+indipendente da \func{alarm}, e nel caso di Linux questo è fatto utilizzando
+direttamente il timer del kernel. Lo standard richiede inoltre che la funzione
+sia utilizzabile senza interferenze con l'uso di \signal{SIGALRM}. La funzione
+prende come argomenti delle strutture di tipo \struct{timespec}, la cui
+definizione è riportata in fig.~\ref{fig:sys_timespec_struct}, il che permette
+di specificare un tempo con una precisione teorica fino al nanosecondo.
+
+La funzione risolve anche il problema di proseguire l'attesa dopo
+l'interruzione dovuta ad un segnale; infatti in tal caso in \param{rem} viene
+restituito il tempo rimanente rispetto a quanto richiesto
+inizialmente,\footnote{con l'eccezione, valida solo nei kernel della serie
+ 2.4, in cui, per i processi riavviati dopo essere stati fermati da un
+ segnale, il tempo passato in stato \texttt{T} non viene considerato nel
+ calcolo della rimanenza.} e basta richiamare la funzione per completare
+l'attesa.
+
+Anche qui però occorre tenere presente che i tempi sono arrotondati, per cui
+la precisione, per quanto migliore di quella ottenibile con \func{sleep}, è
+relativa e in caso di molte interruzioni si può avere una deriva, per questo
+esiste la funzione \func{clock\_nanosleep} (vedi sez.~\ref{sec:sig_timer_adv})
+che permette di specificare un tempo assoluto anziché un tempo relativo.
+
+Chiaramente, anche se il tempo può essere specificato con risoluzioni fino al
+nanosecondo, la precisione di \func{nanosleep} è determinata dalla risoluzione
+temporale del timer di sistema. Perciò la funzione attenderà comunque il tempo
+specificato, ma prima che il processo possa tornare ad essere eseguito
+occorrerà almeno attendere la successiva interruzione del timer di sistema,
+cioè un tempo che a seconda dei casi può arrivare fino a 1/\const{HZ}, (sempre
+che il sistema sia scarico ed il processa venga immediatamente rimesso in
+esecuzione). Per questo motivo il valore restituito in \param{rem} è sempre
+arrotondato al multiplo successivo di 1/\const{HZ}.
+
+Con i kernel della serie 2.4 in realtà era possibile ottenere anche pause più
+precise del centesimo di secondo usando politiche di \textit{scheduling}
+\textit{real-time} come \const{SCHED\_FIFO} o \const{SCHED\_RR} (vedi
+sez.~\ref{sec:proc_real_time}); in tal caso infatti il calcolo sul numero di
+interruzioni del timer veniva evitato utilizzando direttamente un ciclo di
+attesa con cui si raggiungevano pause fino ai 2~ms con precisioni del
+$\mu$s. Questa estensione è stata rimossa con i kernel della serie 2.6, che
+consentono una risoluzione più alta del timer di sistema; inoltre a partire
+dal kernel 2.6.21, \func{nanosleep} può avvalersi del supporto dei timer ad
+alta risoluzione, ottenendo la massima precisione disponibile sull'hardware
+della propria macchina.
+
+
+\subsection{Un esempio elementare}
+\label{sec:sig_sigchld}
+
+Un semplice esempio per illustrare il funzionamento di un gestore di segnale è
+quello della gestione di \signal{SIGCHLD}. Abbiamo visto in
+sez.~\ref{sec:proc_termination} che una delle azioni eseguite dal kernel alla
+conclusione di un processo è quella di inviare questo segnale al padre. In
+generale dunque, quando non interessa elaborare lo stato di uscita di un
+processo, si può completare la gestione della terminazione installando un
+gestore per \signal{SIGCHLD} il cui unico compito sia quello di chiamare
+\func{waitpid} per completare la procedura di terminazione in modo da evitare
+la formazione di \textit{zombie}.\footnote{si ricordi comunque che dal kernel
+ 2.6 seguendo lo standard POSIX.1-2001 per evitare di dover ricevere gli
+ stati di uscita che non interessano basta impostare come azione predefinita
+ quella di ignorare \signal{SIGCHLD}, nel qual caso viene assunta la
+ semantica di System V, in cui il segnale non viene inviato, il sistema non
+ genera \textit{zombie} e lo stato di terminazione viene scartato senza dover
+ chiamare una \func{wait}.}
+
+In fig.~\ref{fig:sig_sigchld_handl} è mostrato il codice contenente una
+implementazione generica di una funzione di gestione per \signal{SIGCHLD},
+(che si trova nei sorgenti allegati nel file \file{SigHand.c}); se ripetiamo i
+test di sez.~\ref{sec:proc_termination}, invocando \cmd{forktest} con
+l'opzione \cmd{-s} (che si limita ad effettuare l'installazione di questa
+funzione come gestore di \signal{SIGCHLD}) potremo verificare che non si ha
+più la creazione di \textit{zombie}.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/hand_sigchild.c}
+ \end{minipage}
+ \normalsize
+ \caption{Codice di una funzione generica di gestione per il segnale
+ \signal{SIGCHLD}.}
+ \label{fig:sig_sigchld_handl}
+\end{figure}
+
+Il codice del gestore è di lettura immediata, come buona norma di
+programmazione (si ricordi quanto accennato sez.~\ref{sec:sys_errno}) si
+comincia (\texttt{\small 6--7}) con il salvare lo stato corrente di
+\var{errno}, in modo da poterlo ripristinare prima del ritorno del gestore
+(\texttt{\small 16--17}). In questo modo si preserva il valore della variabile
+visto dal corso di esecuzione principale del processo, che altrimenti sarebbe
+sovrascritto dal valore restituito nella successiva chiamata di
+\func{waitpid}.
+
+Il compito principale del gestore è quello di ricevere lo stato di
+terminazione del processo, cosa che viene eseguita nel ciclo in
+(\texttt{\small 9--15}). Il ciclo è necessario a causa di una caratteristica
+fondamentale della gestione dei segnali: abbiamo già accennato come fra la
+generazione di un segnale e l'esecuzione del gestore possa passare un certo
+lasso di tempo e niente ci assicura che il gestore venga eseguito prima della
+generazione di ulteriori segnali dello stesso tipo. In questo caso normalmente
+i segnali successivi vengono ``\textsl{fusi}'' col primo ed al processo ne
+viene recapitato soltanto uno.
+
+Questo può essere un caso comune proprio con \signal{SIGCHLD}, qualora capiti
+che molti processi figli terminino in rapida successione. Esso inoltre si
+presenta tutte le volte che un segnale viene bloccato: per quanti siano i
+segnali emessi durante il periodo di blocco, una volta che quest'ultimo sarà
+rimosso verrà recapitato un solo segnale.
+
+Allora, nel caso della terminazione dei processi figli, se si chiamasse
+\func{waitpid} una sola volta, essa leggerebbe lo stato di terminazione per un
+solo processo, anche se i processi terminati sono più di uno, e gli altri
+resterebbero in stato di \textit{zombie} per un tempo indefinito.
+
+Per questo occorre ripetere la chiamata di \func{waitpid} fino a che essa non
+ritorni un valore nullo, segno che non resta nessun processo di cui si debba
+ancora ricevere lo stato di terminazione (si veda sez.~\ref{sec:proc_wait} per
+la sintassi della funzione). Si noti anche come la funzione venga invocata con
+il parametro \const{WNOHANG} che permette di evitare il suo blocco quando
+tutti gli stati di terminazione sono stati ricevuti.
+
+
+
+\section{La gestione avanzata dei segnali}
+\label{sec:sig_adv_control}
+
+Le funzioni esaminate finora fanno riferimento alle modalità più elementari
+della gestione dei segnali; non si sono pertanto ancora prese in
+considerazione le tematiche più complesse, collegate alle varie \textit{race
+ condition} che i segnali possono generare e alla natura asincrona degli
+stessi.
+
+Affronteremo queste problematiche in questa sezione, partendo da un esempio
+che le evidenzi, per poi prendere in esame le varie funzioni che permettono di
+risolvere i problemi più complessi connessi alla programmazione con i segnali,
+fino a trattare le caratteristiche generali della gestione dei medesimi nella
+casistica ordinaria.
+
+
+\subsection{Alcune problematiche aperte}
+\label{sec:sig_example}
+
+Come accennato in sez.~\ref{sec:sig_pause_sleep} è possibile implementare
+\func{sleep} a partire dall'uso di \func{pause} e \func{alarm}. A prima vista
+questo può sembrare di implementazione immediata; ad esempio una semplice
+versione di \func{sleep} potrebbe essere quella illustrata in
+fig.~\ref{fig:sig_sleep_wrong}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/sleep_danger.c}
+ \end{minipage}
+ \normalsize
+ \caption{Una implementazione pericolosa di \func{sleep}.}
+ \label{fig:sig_sleep_wrong}
+\end{figure}
+
+Dato che è nostra intenzione utilizzare \signal{SIGALRM} il primo passo della
+nostra implementazione sarà quello di installare il relativo gestore salvando
+il precedente (\texttt{\small 14--17}). Si effettuerà poi una chiamata ad
+\func{alarm} per specificare il tempo d'attesa per l'invio del segnale a cui
+segue la chiamata a \func{pause} per fermare il programma (\texttt{\small
+ 18--20}) fino alla sua ricezione. Al ritorno di \func{pause}, causato dal
+ritorno del gestore (\texttt{\small 1--9}), si ripristina il gestore originario
+(\texttt{\small 21--22}) restituendo l'eventuale tempo rimanente
+(\texttt{\small 23--24}) che potrà essere diverso da zero qualora
+l'interruzione di \func{pause} venisse causata da un altro segnale.
+
+Questo codice però, a parte il non gestire il caso in cui si è avuta una
+precedente chiamata a \func{alarm} (che si è tralasciato per brevità),
+presenta una pericolosa \textit{race condition}. Infatti, se il processo
+viene interrotto fra la chiamata di \func{alarm} e \func{pause}, può capitare
+(ad esempio se il sistema è molto carico) che il tempo di attesa scada prima
+dell'esecuzione di quest'ultima, cosicché essa sarebbe eseguita dopo l'arrivo
+di \signal{SIGALRM}. In questo caso ci si troverebbe di fronte ad un
+\textit{deadlock}, in quanto \func{pause} non verrebbe mai più interrotta (se
+non in caso di un altro segnale).
+
+Questo problema può essere risolto (ed è la modalità con cui veniva fatto in
+SVr2) usando la funzione \func{longjmp} (vedi sez.~\ref{sec:proc_longjmp}) per
+uscire dal gestore. In questo modo, con una condizione sullo stato di
+uscita di quest'ultima, si può evitare la chiamata a \func{pause}, usando un
+codice del tipo di quello riportato in fig.~\ref{fig:sig_sleep_incomplete}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/sleep_defect.c}
+ \end{minipage}
+ \normalsize
+ \caption{Una implementazione ancora malfunzionante di \func{sleep}.}
+ \label{fig:sig_sleep_incomplete}
+\end{figure}
+
+In questo caso il gestore (\texttt{\small 18--27}) non ritorna come in
+fig.~\ref{fig:sig_sleep_wrong}, ma usa la funzione \func{longjmp}
+(\texttt{\small 25}) per rientrare direttamente nel corpo principale del
+programma. Dato che in questo caso il valore di uscita che verrà restituito da
+\func{setjmp} è 1, grazie alla condizione impostata in (\texttt{\small 9--12})
+si potrà evitare comunque che \func{pause} sia chiamata a vuoto.
+
+Ma anche questa implementazione comporta dei problemi, in questo caso infatti
+non viene gestita correttamente l'interazione con gli altri segnali. Se
+infatti il segnale di allarme interrompe un altro gestore, l'esecuzione non
+riprenderà nel gestore in questione, ma nel ciclo principale, interrompendone
+inopportunamente l'esecuzione. Lo stesso tipo di problemi si presenterebbero
+se si volesse usare questa implementazione di \func{alarm} per stabilire un
+timeout su una qualunque \textit{system call} bloccante.
+
+Un secondo esempio dei problemi a cui si può andare incontro è quello in cui
+si usa un segnale per notificare una qualche forma di evento. In genere quello
+che si fa in questo caso è impostare all'interno del gestore un opportuno flag
+da controllare nel corpo principale del programma, con un codice del tipo di
+quello riportato in fig.~\ref{fig:sig_event_wrong}.
+
+La logica del programma è quella di impostare nel gestore una variabile
+globale preventivamente inizializzata nel programma principale ad un valore
+diverso (\texttt{\small 14--19}). In questo modo dal corpo principale del
+programma si potrà determinare, osservando il contenuto di detta variabile,
+l'occorrenza o meno del segnale, ed eseguire le conseguenti azioni relative
+(\texttt{\small 6--11}).
+
+\begin{figure}[!htbp]
+ \footnotesize\centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/sig_alarm.c}
+ \end{minipage}
+ \normalsize
+ \caption{Un esempio non funzionante del codice per il controllo di un
+ evento generato da un segnale.}
+ \label{fig:sig_event_wrong}
+\end{figure}
+
+Questo è il tipico esempio di caso, già citato in
+sez.~\ref{sec:proc_race_cond}, in cui si genera una \textit{race
+ condition}. Infatti, in una situazione in cui un segnale è già arrivato (e
+quindi \var{flag} è già stata impostata ad 1 nel gestore) se un altro segnale
+arriva immediatamente dopo l'esecuzione del controllo (\texttt{\small 6}) ma
+prima della cancellazione di \var{flag} fatta subito dopo (\texttt{\small 7}),
+la sua occorrenza sarà perduta.
+
+Questi esempi ci mostrano come per poter eseguire una gestione effettiva dei
+segnali occorrono delle funzioni più sofisticate di quelle finora
+illustrate. La funzione \func{signal} infatti ha la sua origine
+nell'interfaccia alquanto primitiva che venne adottata nei primi sistemi Unix,
+ma con questa funzione è sostanzialmente impossibile gestire in maniera
+adeguata di tutti i possibili aspetti con cui un processo deve reagire alla
+ricezione di un segnale.
+
+
+
+\subsection{Gli \textsl{insiemi di segnali} o \textit{signal set}}
+\label{sec:sig_sigset}
+
+\itindbeg{signal~set}
+
+Come evidenziato nel paragrafo precedente, le funzioni di gestione dei segnali
+originarie, nate con la semantica inaffidabile, hanno dei limiti non
+superabili; in particolare non è prevista nessuna funzione che permetta di
+gestire il blocco dei segnali o di verificare lo stato dei segnali pendenti.
+
+Per questo motivo lo standard POSIX.1, insieme alla nuova semantica dei
+segnali ha introdotto una interfaccia di gestione completamente nuova, che
+permette di ottenere un controllo molto più dettagliato. In particolare lo
+standard ha introdotto un nuovo tipo di dato \type{sigset\_t}, che permette di
+rappresentare un \textsl{insieme di segnali} (un \textit{signal set}, come
+viene usualmente chiamato), tale tipo di dato viene usato per gestire il
+blocco dei segnali.
+
+Inizialmente un \textsl{insieme di segnali} veniva rappresentato da un intero
+di dimensione opportuna, di solito pari al numero di bit dell'architettura
+della macchina, ciascun bit del quale era associato ad uno specifico
+segnale. Nel caso di architetture a 32 bit questo comporta un massimo di 32
+segnali distinti e dato che a lungo questi sono stati sufficienti non c'era
+necessità di nessuna struttura più complicata, in questo modo era possibile
+implementare le operazioni direttamente con istruzioni elementari del
+processore.
+
+Oggi questo non è più vero, in particolare con l'introduzione dei segnali
+\textit{real-rime} (che vedremo in sez.~\ref{sec:sig_real_time}). Dato che in
+generale non si può fare conto sulle caratteristiche di una implementazione,
+perché non è detto che si disponga di un numero di bit sufficienti per mettere
+tutti i segnali in un intero, o perché in \type{sigset\_t} possono essere
+immagazzinate ulteriori informazioni, tutte le operazioni devono essere
+effettuate tramite le opportune funzioni di libreria che si curano di
+mascherare i dettagli di basso livello.
+
+Lo standard POSIX.1 definisce cinque funzioni per la manipolazione degli
+insiemi di segnali. Le prime quattro, che consentono di manipolare i contenuti
+di un \textit{signal set}, sono \funcd{sigemptyset}, \funcd{sigfillset},
+\funcd{sigaddset} e \funcd{sigdelset}; i rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{signal.h}
+\fdecl{int sigemptyset(sigset\_t *set)}
+\fdesc{Inizializza un insieme di segnali vuoto.}
+\fdecl{int sigfillset(sigset\_t *set)}
+\fdesc{Inizializza un insieme di segnali pieno.}
+\fdecl{int sigaddset(sigset\_t *set, int signum)}
+\fdesc{Aggiunge un segnale ad un insieme di segnali.}
+\fdecl{int sigdelset(sigset\_t *set, int signum)}
+\fdesc{Rimuove un segnale da un insieme di segnali.}
+}