presenta una pericolosa race condition\index{\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 quest'ultima, cosicché essa
+tempo di attesa scada prima dell'esecuzione di quest'ultima, cosicché essa
sarebbe eseguita dopo l'arrivo di \const{SIGALRM}. In questo caso ci si
troverebbe di fronte ad un deadlock\index{\textit{deadlock}}, in quanto
\func{pause} non verrebbe mai più interrotta (se non in caso di un altro
\label{fig:sig_sleep_incomplete}
\end{figure}
-In questo caso il gestore (\texttt{\small 18-26}) non ritorna come in
-fig.~\ref{fig:sig_sleep_wrong}, ma usa \func{longjmp} (\texttt{\small 24}) per
+In questo caso il gestore (\texttt{\small 18-27}) non ritorna come in
+fig.~\ref{fig:sig_sleep_wrong}, ma usa \func{longjmp} (\texttt{\small 25}) per
rientrare nel corpo principale del programma; dato che in questo caso il
valore di uscita di \func{setjmp} è 1, grazie alla condizione in
(\texttt{\small 9-12}) si evita comunque che \func{pause} sia chiamata a
segnale, e prendere le relative azioni conseguenti (\texttt{\small 6-11}).
Questo è il tipico esempio di caso, già citato in
-sez.~\ref{sec:proc_race_cond}, in cui si genera una race condition
-\index{\textit{race~condition}}; se infatti il segnale arriva immediatamente
-dopo l'esecuzione del controllo (\texttt{\small 6}) ma prima della
-cancellazione del flag (\texttt{\small 7}), la sua occorrenza sarà perduta.
+sez.~\ref{sec:proc_race_cond}, in cui si genera una
+\index{\textit{race~condition}}race condition; se infatti il segnale arriva
+immediatamente dopo l'esecuzione del controllo (\texttt{\small 6}) ma prima
+della cancellazione del flag (\texttt{\small 7}), la sua occorrenza sarà
+perduta.
Questi esempi ci mostrano che per una gestione effettiva dei segnali occorrono
funzioni più sofisticate di quelle illustrate finora, che hanno origine dalla
\subsection{Gli \textsl{insiemi di segnali} o \textit{signal set}}
\label{sec:sig_sigset}
-\index{\textit{signal~set}|(}
+\index{\textit{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 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 ottenete un controllo molto più dettagliato. In particolare lo
+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), che è il tipo di dato che viene usato per gestire
-il blocco dei segnali.
+viene usualmente chiamato), tale tipo di dato viene usato per gestire il
+blocco dei segnali.
In genere un \textsl{insieme di segnali} è rappresentato da un intero di
-dimensione opportuna, di solito si pari al numero di bit dell'architettura
-della macchina\footnote{nel caso dei PC questo comporta un massimo di 32
- segnali distinti, dato che in Linux questi sono sufficienti non c'è
- necessità di nessuna struttura più complicata.}, ciascun bit del quale è
-associato ad uno specifico segnale; in questo modo è di solito possibile
-implementare le operazioni direttamente con istruzioni elementari del
-processore; lo standard POSIX.1 definisce cinque funzioni per la manipolazione
-degli insiemi di segnali: \funcd{sigemptyset}, \funcd{sigfillset},
-\funcd{sigaddset}, \funcd{sigdelset} e \funcd{sigismember}, i cui prototipi
-sono:
+dimensione opportuna, di solito pari al numero di bit dell'architettura della
+macchina,\footnote{nel caso dei PC questo comporta un massimo di 32 segnali
+ distinti: dato che in Linux questi sono sufficienti non c'è necessità di
+ nessuna struttura più complicata.} ciascun bit del quale è associato ad uno
+specifico segnale; in questo modo è di solito possibile implementare le
+operazioni direttamente con istruzioni elementari del processore. Lo standard
+POSIX.1 definisce cinque funzioni per la manipolazione degli insiemi di
+segnali: \funcd{sigemptyset}, \funcd{sigfillset}, \funcd{sigaddset},
+\funcd{sigdelset} e \funcd{sigismember}, i cui prototipi sono:
\begin{functions}
\headdecl{signal.h}
rendendola molto più flessibile e robusta, anche se leggermente più complessa.
La funzione principale dell'interfaccia POSIX.1 per i segnali è
-\funcd{sigaction}. Essa ha sostanzialemente lo stesso uso di \func{signal},
+\funcd{sigaction}. Essa ha sostanzialmente lo stesso uso di \func{signal},
permette cioè di specificare le modalità con cui un segnale può essere gestito
da un processo. Il suo prototipo è:
\begin{prototype}{signal.h}{int sigaction(int signum, const struct sigaction
segnali real-time (vedi sez.~\ref{sec:sig_real_time}) inviati tramite
\func{kill} avvalorano \var{si\_pid} e \var{si\_uid} coi valori corrispondenti
al processo che ha emesso il segnale, \const{SIGILL}, \const{SIGFPE},
-\const{SIGSEGV} e \const{SIGBUS} avvalorano \var{si\_addr} con l'indirizzo cui
-è avvenuto l'errore, \const{SIGIO} (vedi sez.~\ref{sec:file_asyncronous_io})
-avvalora \var{si\_fd} con il numero del file descriptor e \var{si\_band} per i
-dati urgenti su un socket\index{socket}.
+\const{SIGSEGV} e \const{SIGBUS} avvalorano \var{si\_addr} con l'indirizzo in
+cui è avvenuto l'errore, \const{SIGIO} (vedi
+sez.~\ref{sec:file_asyncronous_io}) avvalora \var{si\_fd} con il numero del
+file descriptor e \var{si\_band} per i dati urgenti su un
+socket\index{socket}.
Benché sia possibile usare nello stesso programma sia \func{sigaction} che
\func{signal} occorre molta attenzione, in quanto le due funzioni possono
-
-
\subsection{La gestione della \textsl{maschera dei segnali} o
\textit{signal mask}}
\label{sec:sig_sigmask}
Per evitare i problemi di interferenza con gli altri segnali in questo caso
non si è usato l'approccio di fig.~\ref{fig:sig_sleep_incomplete} evitando
-l'uso di \func{longjmp}. Come in precedenza il gestore (\texttt{\small 35-37})
+l'uso di \func{longjmp}. Come in precedenza il gestore (\texttt{\small 27-30})
non esegue nessuna operazione, limitandosi a ritornare per interrompere il
programma messo in attesa.
-La prima parte della funzione (\texttt{\small 11-15}) provvede ad installare
+La prima parte della funzione (\texttt{\small 6-10}) provvede ad installare
l'opportuno gestore per \const{SIGALRM}, salvando quello originario, che
-sarà ripristinato alla conclusione della stessa (\texttt{\small 28}); il passo
-successivo è quello di bloccare \const{SIGALRM} (\texttt{\small 17-19}) per
+sarà ripristinato alla conclusione della stessa (\texttt{\small 23}); il passo
+successivo è quello di bloccare \const{SIGALRM} (\texttt{\small 11-14}) per
evitare che esso possa essere ricevuto dal processo fra l'esecuzione di
-\func{alarm} (\texttt{\small 21}) e la sospensione dello stesso. Nel fare
+\func{alarm} (\texttt{\small 16}) e la sospensione dello stesso. Nel fare
questo si salva la maschera corrente dei segnali, che sarà ripristinata alla
-fine (\texttt{\small 27}), e al contempo si prepara la maschera dei segnali
+fine (\texttt{\small 22}), e al contempo si prepara la maschera dei segnali
\var{sleep\_mask} per riattivare \const{SIGALRM} all'esecuzione di
\func{sigsuspend}.
i seguenti:
\begin{enumerate*}
\item Leggere la maschera dei segnali corrente e bloccare il segnale voluto
- con \func{sigprocmask}.
+ con \func{sigprocmask};
\item Mandare il processo in attesa con \func{sigsuspend} abilitando la
- ricezione del segnale voluto.
+ ricezione del segnale voluto;
\item Ripristinare la maschera dei segnali originaria.
\end{enumerate*}
Per quanto possa sembrare strano bloccare la ricezione di un segnale per poi
\end{prototype}
La funzione permette di ricavare quali sono i segnali pendenti per il processo
-in corso, cioè i segnali che sono stato inviati dal kernel ma non sono stati
+in corso, cioè i segnali che sono stati inviati dal kernel ma non sono stati
ancora ricevuti dal processo in quanto bloccati. Non esiste una funzione
equivalente nella vecchia interfaccia, ma essa è tutto sommato poco utile,
dato che essa può solo assicurare che un segnale è stato inviato, dato che
gestori, occorre però seguire una certa procedura:
\begin{enumerate}
\item Allocare un'area di memoria di dimensione sufficiente da usare come
- stack alternativo.
+ stack alternativo;
\item Usare la funzione \func{sigaltstack} per rendere noto al sistema
- l'esistenza e la locazione dello stack alternativo.
+ l'esistenza e la locazione dello stack alternativo;
\item Quando si installa un gestore occorre usare \func{sigaction}
specificando il flag \const{SA\_ONSTACK} (vedi tab.~\ref{tab:sig_sa_flag})
per dire al sistema di usare lo stack alternativo durante l'esecuzione del
necessario al gestore gli si può aggiungere questo valore per allocare uno
stack di dimensione sufficiente.
-Come accennato per poter essere usato lo stack per i segnali deve essere
+Come accennato, per poter essere usato, lo stack per i segnali deve essere
indicato al sistema attraverso la funzione \funcd{sigaltstack}; il suo
prototipo è:
\begin{prototype}{signal.h}
\end{functions}
Le due funzioni prendono come primo argomento la variabile su cui viene
-salvato il contesto dello stack per permettere il salto non-locale
-\index{salto~non-locale}; nel caso specifico essa è di tipo
+salvato il contesto dello stack per permettere il
+\index{salto~non-locale}salto non-locale; nel caso specifico essa è di tipo
\type{sigjmp\_buf}, e non \type{jmp\_buf} come per le analoghe di
sez.~\ref{sec:proc_longjmp} in quanto in questo caso viene salvata anche la
maschera dei segnali.
-Nel caso di \func{sigsetjmp} se si specifica un valore di \param{savesigs}
+Nel caso di \func{sigsetjmp}, se si specifica un valore di \param{savesigs}
diverso da zero la maschera dei valori sarà salvata in \param{env} e
ripristinata in un successivo \func{siglongjmp}; quest'ultima funzione, a
parte l'uso di \type{sigjmp\_buf} per \param{env}, è assolutamente identica a
\item[I segnali non sono accumulati]
se più segnali vengono generati prima dell'esecuzione di un gestore
questo sarà eseguito una sola volta, ed il processo non sarà in grado di
- accorgersi di quante volte l'evento che ha generato il segnale è accaduto.
+ accorgersi di quante volte l'evento che ha generato il segnale è accaduto;
\item[I segnali non trasportano informazione]
i segnali classici non prevedono altra informazione sull'evento
che li ha generati se non il fatto che sono stati emessi (tutta
- l'informazione che il kernel associa ad un segnale è il suo numero).
+ l'informazione che il kernel associa ad un segnale è il suo numero);
\item[I segnali non hanno un ordine di consegna]
l'ordine in cui diversi segnali vengono consegnati è casuale e non
prevedibile. Non è possibile stabilire una priorità per cui la reazione a