Rimessi insieme i vecchi pezzi.
[gapil.git] / signal.tex
index 966e32a1aa0759a2d1d6b15210171c3f2680d5e7..b60bd7aeeb0c5cab3b9e110fb6a2ce81cbd56da2 100644 (file)
@@ -84,6 +84,20 @@ attivo.
 In questo caso è possibile una situazione in cui i segnali possono essere
 perduti. Si consideri il seguente segmento di codice, in cui la prima
 operazione del manipolatore è quella di reinstallare se stesso: 
+\footnotesize
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+    int sig_handler();            /* handler function */
+    ...
+    signal(SIGINT, sig_handler);  /* establish handler */
+    ...
+
+int sig_handler() 
+{
+    signal(SIGINT, sig_handler);  /* restablish handler */
+    ...                           /* process signal */
+}
+\end{lstlisting}
+\normalsize
 se un secondo segnale arriva prima che il manipolatore invocato dal primo
 abbia eseguito la reinstallazione di se stesso il segnale può essere perso o
 causare il comportamento originale assegnato al segnale (in genere la
@@ -418,7 +432,7 @@ stato dello stack e delle variabili al momento della ricezione del segnale.
 \end{table}
 
 La descrizione dettagliata del significato dei vari segnali, raggruppati per
-tipologia, verrà affrontate nel seguito.
+tipologia, verrà affrontate nei paragrafi successivi.
 
 
 \subsection{Segnali di errore di programma}
@@ -1621,44 +1635,62 @@ 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 manipolatore, in questo caso
 l'esecuzione non riprenderà nel manipolatore in questione, ma nel ciclo
-principale, interrompendone inopportunamente l'esecuzione.  
+principale, interrompendone inopportunamente l'esecuzione.  Lo stesso tipo di
+problemi si presenterebbero se si volesse usare \func{alarm} per stabilire un
+timeout su una qualunque system call bloccante.
 
-Lo stesso tipo di problema si presenterebbe se si volesse usare \func{alarm}
-per stabilire un timeout su una sistem call bloccante. Un secondo esempio è
-quello in cui si usa il segnale per notificare una quelche forma di evento; in
-genere quello che si fa in questo caso è settare nel manipolatore un opportuno
-flag da controllare nel corpo principale del programma (con un codice del tipo
-di quello riportato in 
+Un secondo esempio è quello in cui si usa il segnale per notificare una
+quelche forma di evento; in genere quello che si fa in questo caso è settare
+nel manipolatore un opportuno flag da controllare nel corpo principale del
+programma (con un codice del tipo di quello riportato in
+\secref{fig:sig_event_wrong}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}{}
 sig_atomic_t flag;
-unsigned int control(unsigned int seconds)
+int main()
 {
-    da fare
+    flag = 0;
+    ...
+    if (flag) {         /* test if signal occurred */
+        flag = 0;       /* reset flag */ 
+        do_response();  /* do things */
+    } else {
+        do_other();     /* do other things */
+    }
+    ...
 }
 void alarm_hand(int sig) 
 {
     /* set the flag 
     flag = 1;
+    return;
 }      
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
-  \caption{Un esempio non funzionante di restituzione di un evento da parte di
-    un segnale.} 
+  \caption{Un esempio non funzionante del codice per il controllo di un
+    evento generato da un segnale.}
   \label{fig:sig_event_wrong}
 \end{figure}
 
+La logica è quella di far settare al manipolatore (\texttt{\small 14-19}) una
+variabile globale preventivamente inizializzata nel programma principale, il
+quale potrà determinare, osservandone il contenuto, l'occorrenza o meno del
+segnale, e prendere le relative azioni conseguenti (\texttt{\small 6-11}).
 
+Questo è il tipico esempio di caso, già citato in \secref{sec:proc_race_cond},
+in cui si genera una 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.
 
-È per questo motivo che occorrono funzioni più sofisticate della semplice
-\func{signal} che permettano di gestire i segnali in maniera più completa.
-
-
-
+Questi esempi ci mostrano che per una gestione effettiva dei segnali occorrono
+funzioni più sofisticate della semplice interfaccia dei primi sistemi Unix,
+che permettano di gestire tutti i possibili aspetti con cui un processo deve
+reagire alla ricezione di un segnale.
 
 
 
@@ -1873,14 +1905,20 @@ permettono si bloccare temporaneamente (o di eliminare completamente, settando
 \macro{SIG\_IGN} come azione) la consegna dei segnali ad un processo. Questo è
 fatto specificando la cosiddetta \textit{signal mask} del
 processo\footnote{nel caso di Linux essa è mantenuta dal campo \var{blocked}
-  della relativa \var{task\_struct}} che viene espressa come il signal set dei
-segnali la cui consegna è bloccata. Abbiamo accennato in
+  della \var{task\_struct} del processo.} che viene espressa come il signal
+set dei segnali la cui consegna è bloccata. Abbiamo accennato in
 \secref{sec:proc_fork} che la \textit{signal mask} viene ereditata dal padre
 alla creazione di un processo figlio, e abbiamo visto al paragrafo precedente
 che essa può essere specificata, durante l'esecuzione di un manipolatore,
 attraverso l'uso dal campo \var{sa\_mask} di \var{sigaction}.
 
-Uno dei problemi evidenziatisi con l'esempio di 
+Uno dei problemi evidenziatisi con l'esempio di \secref{fig:sig_event_wrong} è
+che in molti casi è necessario proteggere delle sezioni di codice (nel caso la
+sezione fra il test e la eventuale cancellazione del flag che testimoniava
+l'avvenuta occorrenza del segnale) in modo da essere sicuri che essi siano
+eseguiti senza interruzioni. Le operazioni più semplici, come l'assegnazione o
+il controllo di una variabile di norma (per essere sicuri si può usare il tipo
+\type{sig\_atomic\_t}).