Inizio delle considerazioni sull'uso della shared memory.
[gapil.git] / signal.tex
index a595a54d9d1cd8c8cb29a9c44efc78e3ebe8c7c4..755f19c2cf6385d237fc22b0c3f7d2604f5213fe 100644 (file)
@@ -394,7 +394,8 @@ stato dello stack e delle variabili al momento della ricezione del segnale.
     \const{SIGPROF}  &SL & A & Timer del profiling scaduto                   \\
     \const{SIGSYS}   &SL & C & Argomento sbagliato per una subroutine (SVID) \\
     \const{SIGTRAP}  &SL & C & Trappole per un Trace/breakpoint              \\
-    \const{SIGURG}   &SLB& B & Ricezione di una urgent condition su un socket\\
+    \const{SIGURG}   &SLB& B & Ricezione di una \textit{urgent condition} su 
+                               un socket\index{socket}\\
     \const{SIGVTALRM}&SLB& A & Virtual alarm clock                           \\
     \const{SIGXCPU}  &SLB& C & Ecceduto il limite sul CPU time               \\
     \const{SIGXFSZ}  &SLB& C & Ecceduto il limite sulla dimensione dei file  \\
@@ -431,11 +432,11 @@ proibita) e l'esecuzione non pu
 
 In genere si intercettano questi segnali per permettere al programma di
 terminare in maniera pulita, ad esempio per ripristinare le impostazioni della
-console o eliminare i file di lock prima dell'uscita.  In questo caso il
-gestore deve concludersi ripristinando l'azione predefinita e rialzando il
-segnale, in questo modo il programma si concluderà senza effetti spiacevoli,
-ma riportando lo stesso stato di uscita che avrebbe avuto se il gestore non ci
-fosse stato.
+console o eliminare i file di lock\index{file!di lock} prima dell'uscita.  In
+questo caso il gestore deve concludersi ripristinando l'azione predefinita e
+rialzando il segnale, in questo modo il programma si concluderà senza effetti
+spiacevoli, ma riportando lo stesso stato di uscita che avrebbe avuto se il
+gestore non ci fosse stato.
 
 L'azione predefinita per tutti questi segnali è causare la terminazione del
 processo che li ha causati. In genere oltre a questo il segnale provoca pure
@@ -591,12 +592,13 @@ generare questi segnali.
 L'azione predefinita è di essere ignorati. Questi segnali sono:
 \begin{basedescript}{\desclabelwidth{2.0cm}}
 \item[\const{SIGIO}] Questo segnale viene inviato quando un file descriptor è
-  pronto per eseguire dell'input/output. In molti sistemi solo i socket e i
-  terminali possono generare questo segnale, in Linux questo può essere usato
-  anche per i file, posto che la \func{fcntl} abbia avuto successo.
+  pronto per eseguire dell'input/output. In molti sistemi solo i
+  socket\index{socket} e i terminali possono generare questo segnale, in Linux
+  questo può essere usato anche per i file, posto che la \func{fcntl} abbia
+  avuto successo.
 \item[\const{SIGURG}] Questo segnale è inviato quando arrivano dei dati
-  urgenti o \textit{out of band} su di un socket; per maggiori dettagli al
-  proposito si veda \secref{sec:xxx_urgent_data}.
+  urgenti o \textit{out of band} su di un socket\index{socket}; per maggiori
+  dettagli al proposito si veda \secref{sec:xxx_urgent_data}.
 \item[\const{SIGPOLL}] Questo segnale è equivalente a \const{SIGIO}, è
   definito solo per compatibilità con i sistemi System V.
 \end{basedescript}
@@ -807,7 +809,8 @@ eseguito prima che la system call sia ritornata.  Un elenco dei casi in cui si
 presenta questa situazione è il seguente:
 \begin{itemize}
 \item la lettura da file che possono bloccarsi in attesa di dati non ancora
-  presenti (come per certi file di dispositivo, i socket o le pipe).
+  presenti (come per certi file di dispositivo\index{file!di dispositivo}, i
+  socket\index{socket} o le pipe).
 \item la scrittura sugli stessi file, nel caso in cui dati non possano essere
   accettati immediatamente.
 \item l'apertura di un file di dispositivo che richiede operazioni non
@@ -1381,16 +1384,16 @@ conclusione di un processo 
 padre.\footnote{in realtà in SVr4 eredita la semantica di System V, in cui il
   segnale si chiama \const{SIGCLD} e viene trattato in maniera speciale; in
   System V infatti se si imposta esplicitamente l'azione a \const{SIG\_IGN} il
-  segnale non viene generato ed il sistema non genera zombie (lo stato di
-  terminazione viene scartato senza dover chiamare una \func{wait}). L'azione
-  predefinita è 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 \const{SIGCLD} come sinonimo di \const{SIGCHLD}.} 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
-\const{SIGCHLD} il cui unico compito sia quello chiamare \func{waitpid} per
-completare la procedura di terminazione in modo da evitare la formazione di
-zombie.
+  segnale non viene generato ed il sistema non genera zombie\index{zombie} (lo
+  stato di terminazione viene scartato senza dover chiamare una \func{wait}).
+  L'azione predefinita è 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 \const{SIGCLD} come sinonimo di \const{SIGCHLD}.} 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 \const{SIGCHLD} il cui unico compito sia quello chiamare
+\func{waitpid} per completare la procedura di terminazione in modo da evitare
+la formazione di zombie\index{zombie}.
 
 In \figref{fig:sig_sigchld_handl} è mostrato il codice contenente una
 implementazione generica di una routine di gestione per \const{SIGCHLD}, (che
@@ -1398,7 +1401,7 @@ si trova nei sorgenti allegati nel file \file{SigHand.c}); se ripetiamo i test
 di \secref{sec:proc_termination}, invocando \cmd{forktest} con l'opzione
 \cmd{-s} (che si limita ad effettuare l'installazione di questa funzione come
 gestore di \const{SIGCHLD}) potremo verificare che non si ha più la creazione
-di zombie.
+di zombie\index{zombie}.
 
 %  è pertanto
 % naturale usare un esempio che ci permette di concludere la trattazione della
@@ -1406,16 +1409,9 @@ di zombie.
 % In questo caso si è tratterà di illustrare un esempio relativo ad un
 % gestore per che è previsto ritornare,
 
-
 \begin{figure}[!htb]
   \footnotesize 
   \begin{lstlisting}{}
-#include <errno.h>       /* error symbol definitions */
-#include <signal.h>      /* signal handling declarations */
-#include <sys/types.h>
-#include <sys/wait.h>
-#include "macro.h"
-
 void HandSigCHLD(int sig)
 {
     int errno_save;
@@ -1471,7 +1467,7 @@ rimosso sar
 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 zombie per un tempo indefinito.
+resterebbero in stato di zombie\index{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
@@ -1559,8 +1555,8 @@ 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 sarebbe eseguita dopo
 l'arrivo di \const{SIGALRM}. In questo caso ci si troverebbe di fronte ad un
-deadlock, in quanto \func{pause} non verrebbe mai più interrotta (se non in
-caso di un altro segnale).
+deadlock\index{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 \secref{sec:proc_longjmp}) per
@@ -1934,7 +1930,7 @@ 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 \secref{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.
+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
@@ -1960,17 +1956,15 @@ typedef void SigFunc(int);
 inline SigFunc * Signal(int signo, SigFunc *func) 
 {
     struct sigaction new_handl, old_handl;
-    new_handl.sa_handler=func;
+    new_handl.sa_handler = func;
     /* clear signal mask: no signal blocked during execution of func */
-    if (sigemptyset(&new_handl.sa_mask)!=0){  /* initialize signal set */
-        perror("cannot initializes the signal set to empty"); /* see mess. */
-        exit(1);
+    if (sigemptyset(&new_handl.sa_mask)!=0){        /* initialize signal set */
+        return SIG_ERR;
     }
-    new_handl.sa_flags=0;                  /* init to 0 all flags */
+    new_handl.sa_flags=0;                             /* init to 0 all flags */
     /* change action for signo signal */
-    if (sigaction(signo,&new_handl,&old_handl)){ 
-        perror("sigaction failed on signal action setting");
-        exit(1);
+    if (sigaction(signo, &new_handl, &old_handl)){ 
+        return SIG_ERR;
     }
     return (old_handl.sa_handler);
 }
@@ -1982,10 +1976,29 @@ inline SigFunc * Signal(int signo, SigFunc *func)
 \end{figure}
 
 Per questo motivo si è provveduto, per mantenere un'interfaccia semplificata
-che abbia le stesse caratteristiche di \func{signal}, a definire una funzione
-equivalente attraverso \func{sigaction}; la funzione è \code{Signal}, e si
-trova definita nel file \file{SigHand.c} (nei sorgenti allegati), e riportata
-in \figref{fig:sig_Signal_code}. La riutilizzeremo spesso in seguito.
+che abbia le stesse caratteristiche di \func{signal}, a definire attraverso
+\func{sigaction} una funzione equivalente, il cui codice è riportato in
+\figref{fig:sig_Signal_code} (il codice completo si trova nel file
+\file{SigHand.c} nei sorgenti allegati).  Si noti come, essendo la funzione
+estremamente semplice, è definita come \direct{inline}.\footnote{la direttiva
+  \direct{inline} viene usata per dire al compilatore di trattare la funzione
+  cui essa fa riferimento in maniera speciale inserendo il codice direttamente
+  nel testo del programma.  Anche se i compilatori più moderni sono in grado
+  di effettuare da soli queste manipolazioni (impostando le opportune
+  ottimizzazioni) questa è una tecnica usata per migliorare le prestazioni per
+  le funzioni piccole ed usate di frequente (in particolare nel kernel, dove
+  in certi casi le ottimizzazioni dal compilatore, tarate per l'uso in user
+  space, non sono sempre adatte). In tal caso infatti le istruzioni per creare
+  un nuovo frame nello stack per chiamare la funzione costituirebbero una
+  parte rilevante del codice, appesantendo inutilmente il programma.
+  Originariamente questo comportamento veniva ottenuto con delle macro, ma
+  queste hanno tutta una serie di problemi di sintassi nel passaggio degli
+  argomenti (si veda ad esempio \cite{PratC}) che in questo modo possono
+  essere evitati.}
+
+
+
+
 
 \subsection{La gestione della \textsl{maschera dei segnali} o 
   \textit{signal mask}}
@@ -2169,8 +2182,9 @@ segnale, i passi sono sempre i seguenti:
 \item Ripristinare la maschera dei segnali originaria.
 \end{enumerate*}
 Per quanto possa sembrare strano bloccare la ricezione di un segnale per poi
-riabilitarla immediatamente dopo, in questo modo si evita il deadlock dovuto
-all'arrivo del segnale prima dell'esecuzione di \func{sigsuspend}.
+riabilitarla immediatamente dopo, in questo modo si evita il
+deadlock\index{deadlock} dovuto all'arrivo del segnale prima dell'esecuzione
+di \func{sigsuspend}.
 
 
 \subsection{Ulteriori funzioni di gestione}