X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=signal.tex;h=f53e50b04d572b4bba0022ca38ede2e5da24dccf;hp=246c308c1f36bb0ab62cfe6ca999cdd6fdd5ed10;hb=bf78d63598adf72d71aeea3c32277dd63484bb02;hpb=9c6ea14a2d89e1cb76b4dd8683542f71c9dcf107 diff --git a/signal.tex b/signal.tex index 246c308..f53e50b 100644 --- a/signal.tex +++ b/signal.tex @@ -120,8 +120,8 @@ int sig_handler() Questa è la ragione per cui l'implementazione dei segnali secondo questa semantica viene chiamata \textsl{inaffidabile}; infatti la ricezione del segnale e la reinstallazione del suo manipolatore non sono operazioni -atomiche, e sono sempre possibili delle race condition (sull'argomento vedi -quanto detto in \secref{sec:proc_multi_prog}). +atomiche, e sono sempre possibili delle race condition\index{race condition} +(sull'argomento vedi quanto detto in \secref{sec:proc_multi_prog}). Un'altro problema è che in questa semantica non esiste un modo per bloccare i segnali quando non si vuole che arrivino; i processi possono ignorare il @@ -242,7 +242,8 @@ Un programma pu \secref{sec:sig_sigaction}). Se si è installato un manipolatore sarà quest'ultimo ad essere eseguito alla notifica del segnale. Inoltre il sistema farà si che mentre viene eseguito il manipolatore di un segnale, quest'ultimo -venga automaticamente bloccato (così si possono evitare race condition). +venga automaticamente bloccato (così si possono evitare race +condition\index{race condition}). Nel caso non sia stata specificata un'azione, viene utilizzata l'azione standard che (come vedremo in \secref{sec:sig_standard}) è propria di ciascun @@ -411,9 +412,9 @@ tipologia, verr \label{sec:sig_prog_error} Questi segnali sono generati quando il sistema, o in certi casi direttamente -l'hardware (come per i page fault non validi) rileva un qualche errore -insanabile nel programma in esecuzione. In generale la generazione di questi -segnali significa che il programma ha dei gravi problemi (ad esempio ha +l'hardware (come per i \textit{page fault} non validi) rileva un qualche +errore insanabile nel programma in esecuzione. In generale la generazione di +questi segnali significa che il programma ha dei gravi problemi (ad esempio ha dereferenziato un puntatore non valido o ha eseguito una operazione aritmetica proibita) e l'esecuzione non può essere proseguita. @@ -1121,7 +1122,7 @@ illustrati in precedenza usare; i possibili valori sono riportati in Il valore della struttura specificata \param{value} viene usato per settare 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 \var{itimerval}, definita in \figref{fig:file_stat_struct}. +struttura \type{itimerval}, definita in \figref{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 @@ -1145,7 +1146,7 @@ struct itimerval \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{itimerval}, che definisce i valori dei timer di + \caption{La struttura \type{itimerval}, che definisce i valori dei timer di sistema.} \label{fig:sig_itimerval} \end{figure} @@ -1472,8 +1473,9 @@ tutti gli stati di terminazione sono stati ricevuti. Le funzioni esaminate finora fanno riferimento ad alle modalità più elementari della gestione dei segnali; non si sono pertanto ancora prese in -considerazione le tematiche più complesse, collegate alle varie race condition -che i segnali possono generare e alla natura asincrona degli stessi. +considerazione le tematiche più complesse, collegate alle varie race +condition\index{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 @@ -1540,13 +1542,13 @@ unsigned int sleep(unsigned int seconds) 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 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 sarebbe eseguita dopo l'arrivo di -\macro{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). +presenta una pericolosa race condition\index{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 sarebbe eseguita dopo +l'arrivo di \macro{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). 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 @@ -1650,10 +1652,10 @@ quale potr 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. +in cui si genera una race condition\index{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 @@ -1852,19 +1854,20 @@ in \tabref{tab:sig_sa_flag}. \end{table} Come si può notare in \figref{fig:sig_sigaction} \func{sigaction} -permette\footnote{La possibilità è prevista dallo standard POSIX.1b, ma in - Linux è stata aggiunta a partire dai kernel della serie 2.2.x. In precedenza - era possibile ottenere alcune informazioni addizionali usando - \var{sa\_handler} con un secondo parametro addizionale di tipo \var{struct - sigcontext}, che adesso è deprecato.} di utilizzare due forme diverse di -manipolatore, da specificare, a seconda dell'uso o meno del flag -\macro{SA\_SIGINFO}, rispettivamente attraverso i campi \var{sa\_sigaction} o -\var{sa\_handler}, (che devono essere usati in maniera alternativa, in certe -implementazioni questi vengono addirittura definiti come \ctyp{union}): la -prima è quella classica usata anche con \func{signal}, la seconda permette -invece di usare un manipolatore in grado di ricevere informazioni più -dettagliate dal sistema, attraverso la struttura \var{siginfo\_t}, riportata -in \figref{fig:sig_siginfo_t}. +permette\footnote{La possibilità è prevista dallo standard POSIX.1b, ed è + stata aggiunta a partire dai kernel della serie 2.1.x con l'introduzione dei + segnali real-time (vedi \secref{sec:sig_real_time}). In precedenza era + possibile ottenere alcune informazioni addizionali usando \var{sa\_handler} + con un secondo parametro addizionale di tipo \var{struct sigcontext}, che + adesso è deprecato.} di utilizzare due forme diverse di manipolatore, da +specificare, a seconda dell'uso o meno del flag \macro{SA\_SIGINFO}, +rispettivamente attraverso i campi \var{sa\_sigaction} o \var{sa\_handler}, +(che devono essere usati in maniera alternativa, in certe implementazioni +questi vengono addirittura definiti come \ctyp{union}): la prima è quella +classica usata anche con \func{signal}, la seconda permette invece di usare un +manipolatore in grado di ricevere informazioni più dettagliate dal sistema, +attraverso la struttura \type{siginfo\_t}, riportata in +\figref{fig:sig_siginfo_t}. \begin{figure}[!htb] \footnotesize \centering @@ -1889,7 +1892,7 @@ siginfo_t { \end{lstlisting} \end{minipage} \normalsize - \caption{La struttura \var{siginfo\_t}.} + \caption{La struttura \type{siginfo\_t}.} \label{fig:sig_siginfo_t} \end{figure} @@ -2048,15 +2051,15 @@ occorre ricordare che qualunque modifica alla maschera dei segnali viene perduta alla conclusione del terminatore. Benché con l'uso di \func{sigprocmask} si possano risolvere la maggior parte -dei casi di race condition restano aperte alcune possibilità legate all'uso di -\func{pause}; il caso è simile a quello del problema illustrato nell'esempio -di \secref{fig:sig_sleep_incomplete}, e cioè la possibilità che il processo -riceva il segnale che si intende usare per uscire dallo stato di attesa -invocato con \func{pause} immediatamente prima dell'esecuzione di -quest'ultima. Per poter effettuare atomicamente la modifica della maschera dei -segnali (di solito attivandone uno specifico) insieme alla sospensione del -processo lo standard POSIX ha previsto la funzione \func{sigsuspend}, il cui -prototipo è: +dei casi di race condition\index{race condition} restano aperte alcune +possibilità legate all'uso di \func{pause}; il caso è simile a quello del +problema illustrato nell'esempio di \secref{fig:sig_sleep_incomplete}, e cioè +la possibilità che il processo riceva il segnale che si intende usare per +uscire dallo stato di attesa invocato con \func{pause} immediatamente prima +dell'esecuzione di quest'ultima. Per poter effettuare atomicamente la modifica +della maschera dei segnali (di solito attivandone uno specifico) insieme alla +sospensione del processo lo standard POSIX ha previsto la funzione +\func{sigsuspend}, il cui prototipo è: \begin{prototype}{signal.h} {int sigsuspend(const sigset\_t *mask)} @@ -2146,10 +2149,10 @@ fine (\texttt{\small 27}), e al contempo si prepara la maschera dei segnali \var{sleep\_mask} per riattivare \macro{SIGALRM} all'esecuzione di \func{sigsuspend}. -In questo modo non sono più possibili race condition dato che \macro{SIGALRM} -viene disabilitato con \func{sigprocmask} fino alla chiamata di -\func{sigsuspend}. Questo metodo è assolutamente generale e può essere -applicato a qualunque altra situazione in cui si deve attendere per un +In questo modo non sono più possibili race condition\index{race conditionx} +dato che \macro{SIGALRM} viene disabilitato con \func{sigprocmask} fino alla +chiamata di \func{sigsuspend}. Questo metodo è assolutamente generale e può +essere applicato a qualunque altra situazione in cui si deve attendere per un segnale, i passi sono sempre i seguenti: \begin{enumerate} \item Leggere la maschera dei segnali corrente e bloccare il segnale voluto @@ -2332,6 +2335,50 @@ parte l'uso di \type{sigjmp\_buf} per \param{env}, \func{longjmp}. + +\subsection{I segnali real-time} +\label{sec:sig_real_time} + + +Lo standard POSIX.1b, nel definire una serie di nuove interfacce per i servizi +real-time, ha introdotto una estensione del modello classico dei segnali che +presenta dei significativi miglioramenti,\footnote{questa estensione è stata + introdotta in Linux a partire dal kernel 2.1.43(?), e dalle \acr{glibc} + 2.1(?).} in particolare sono stati superati tre limiti fondamentali dei +segnali classici: +\begin{description} +\item[I segnali non sono accumulati] se più segnali vengono generati prima + dell'esecuzione di un manipolatore 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. +\item[I segnali non trasportano informazione] i segnali classici non prevedono + prevedono altra informazione sull'evento che li ha generati che il loro + numero. +\item[I segnali non hanno un ordine di consegna] l'ordine in cui diversi + segnali vengono consegnati è casuale e non prevedibile, e dipende dalla + situazione in cui si trova il kernel al momento. +\end{description} + +Le nuove caratteristiche aggiunte a quelli che vengono chiamati +\textsl{segnali real-time}, sono le seguenti: + +\begin{itemize*} +\item la creazione di una coda che permette di consegnare istanze multiple + dello stesso segnale qualora esso venga inviato più volte prima + dell'esecuzione del manipolatore. +\item l'introduzione di una priorità nella consegna dei segnali (segnali a + priorità più alta vengono consegnati prima). +\item la possibilità di restituire dei dati al manipolatore, attraverso l'uso + della struttura \type{siginfo\_t} e dei manipolatori di tipo + \var{sa_sigaction}. +\end{itemize*} + +Per non interferire con i segnali standard POSIX i nuovi segnali sono +definiti, in \file{signal.h} a partire da un valore minimo \macro{SIGRTMIN} +fino \macro{SIGRTMAX} ad un massimo di + + + %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil"