X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=signal.tex;h=e6c75e6364accc1ff465294e9ccb2cba8492e43a;hb=3e1677c91b3f6c2b2ad8554d923300fe61bcf7d0;hp=78d5080e82d5c51be297921fdcdb1aa9bec1b7a0;hpb=c2e762abed93fe970c6c4d019a8bfe95fadb4efa;p=gapil.git diff --git a/signal.tex b/signal.tex index 78d5080..e6c75e6 100644 --- a/signal.tex +++ b/signal.tex @@ -2594,12 +2594,16 @@ prototipo è: {La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EFAULT}] si sono specificati indirizzi non validi. - \item[\errcode{EINVAL}] si è specificato un numero di segnale invalido. + \item[\errcode{EFAULT}] l'indirizzo di \param{mask} non è valido. + \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale. \end{errlist} } \end{funcproto} +La funzione imposta la maschera dei segnali indicata da \param{mask} e pone in +attesa il processo. Ritorna solo con la ricezione di un segnale, con un errore +di \errval{EINTR}, a meno che il segnale non termini il processo. + Come esempio dell'uso di queste funzioni proviamo a riscrivere un'altra volta l'esempio di implementazione di \code{sleep}. Abbiamo accennato in sez.~\ref{sec:sig_sigaction} come con \func{sigaction} sia possibile bloccare @@ -2920,10 +2924,11 @@ stata già vista in fig.~\ref{fig:sig_siginfo_t}, nella trattazione dei gestori in forma estesa. In particolare i campi di \struct{siginfo\_t} utilizzati dai segnali -\textit{real-time} sono \var{si\_pid} e \var{si\_uid} in cui vengono -memorizzati rispettivamente il \ids{PID} e l'\ids{UID} effettivo del processo -che ha inviato il segnale, ed il campo \var{si\_value} che viene usato -appositamente per poter restituire dei dati al gestore. +\textit{real-time} sono \var{si\_pid} e \var{si\_uid} in cui vengono riportati +rispettivamente il \ids{PID} e l'\ids{UID} effettivo del processo che ha +inviato il segnale, e lo specifico campo \var{si\_value}. Questo campo viene +indicato in fig.~\ref{fig:sig_siginfo_t} come di tipo \type{sigval\_t}; se ne +è riportata la definizione in fig.~\ref{fig:sig_sigval}. \begin{figure}[!htb] \footnotesize \centering @@ -2936,27 +2941,24 @@ appositamente per poter restituire dei dati al gestore. \label{fig:sig_sigval} \end{figure} -Detto campo, la cui definizione è riportata in fig.~\ref{fig:sig_sigval}, -viene indicato con il tipo di dato \type{sigval\_t}, che è una \dirct{union} -di tipo \struct{sigval} in cui può essere memorizzato o un valore numerico, se -usata nella forma \var{sival\_int}, o un puntatore, se usata nella forma -\var{sival\_ptr}. - -L'unione viene usata dai segnali \textit{real-time} e da vari meccanismi di -notifica per restituire dati al gestore del segnale in \var{si\_value}. Un -campo di tipo \type{sigval\_t} è presente anche nella struttura -\struct{sigevent} (definita in fig.~\ref{fig:struct_sigevent}) che viene usata -dai meccanismi di notifica come quelli per i timer POSIX (vedi -sez.~\ref{sec:sig_timer_adv}), l'I/O asincrono (vedi -sez.~\ref{sec:file_asyncronous_io}) o le code di messaggi POSIX (vedi -sez.~\ref{sec:ipc_posix_mq}). -A causa delle loro caratteristiche, la funzione \func{kill} non è adatta ad -inviare segnali \textit{real-time}, poiché non è in grado di fornire alcun -valore per il campo \var{si\_value} restituito nella struttura -\struct{siginfo\_t} prevista da un gestore in forma estesa. Per questo motivo -lo standard ha previsto una nuova funzione, \funcd{sigqueue}, il cui prototipo -è: +Si tratta quindi di una unione \struct{sigval} con due possibili campi +alternativi in cui può essere memorizzato o un valore numerico, se usata con +\var{sival\_int}, o un puntatore, se usata con \var{sival\_ptr}. L'unione +viene usata dai segnali \textit{real-time}, ma anche da vari altri meccanismi +di notifica, per inviare eventuali informazioni aggiuntive al gestore del +segnale in \var{si\_value}. Ad esempio un campo di tipo \type{sigval\_t} è +presente anche nella struttura \struct{sigevent} (definita in +fig.~\ref{fig:struct_sigevent}) che viene usata da vari meccanismi di notifica +come quelli per i timer POSIX (che vedremo in sez.~\ref{sec:sig_timer_adv}), +quello dell'I/O asincrono (che vedremo in sez.~\ref{sec:file_asyncronous_io}) +o dalle code di messaggi POSIX (che vedremo in sez.~\ref{sec:ipc_posix_mq}). + +A causa di questa loro caratteristica, la funzione \func{kill}, pure essendo +utilizzabile, non è adatta ad inviare segnali \textit{real-time}, perché non è +in grado di impostare alcun valore per il campo \var{si\_value}. Per questo +motivo lo standard POSIX ha previsto una nuova funzione, \funcd{sigqueue}, il +cui prototipo è: \begin{funcproto}{ \fhead{signal.h} @@ -2978,7 +2980,6 @@ lo standard ha previsto una nuova funzione, \funcd{sigqueue}, il cui prototipo } \end{funcproto} - La funzione invia il segnale indicato dall'argomento \param{signo} al processo indicato dall'argomento \param{pid}. Per il resto il comportamento della funzione è analogo a quello di \func{kill}, ed i privilegi occorrenti ad @@ -3020,11 +3021,10 @@ prima di queste è \funcd{sigwait}, il cui prototipo è: \fdecl{int sigwait(const sigset\_t *set, int *sig)} \fdesc{Attende la ricezione di un segnale.} } -{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual - caso \var{errno} assumerà uno dei valori: +{La funzione ritorna $0$ in caso di successo ed un valore positivo in caso di + errore con valore secondo la lista seguente: \begin{errlist} - \item[\errcode{EINTR}] la funzione è stata interrotta. - \item[\errcode{EINVAL}] si è specificato un valore non valido per + \item[\errcode{EINVAL}] \param{set} contiene un numero di segnale non valido \end{errlist} ed inoltre \errval{EFAULT} nel suo significato generico.} \end{funcproto} @@ -3098,6 +3098,55 @@ che venga eseguita l'azione predefinita, devono essere mascherati per tutti i \textit{thread}, compreso quello dedicato alla gestione, che potrebbe riceverlo fra due chiamate successive. +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{\codesamplewidth} + \includecodesample{listati/rtsigvalsend.c} + \end{minipage} + \normalsize + \caption{Corpo principale di un programma di invio di segnali + \textit{real-time}.} + \label{fig:sig_rtsival_main} +\end{figure} + +Come esempio elementare dell'uso dei segnali \textit{real-time}, e della +possibilità di inviare informazioni al gestore degli stessi con +\func{sigqueue}, si è riportato in fig.~\ref{fig:sig_rtsival_main} il corpo +principale di un programma elementare che legge dal terminale un valore +numerico, ed utilizza un segnale \textit{real-time} per inviarlo al gestore +dello stesso. Nel codice sono stati trascurati i controlli dei valori di +ritorno delle varie funzioni per mantenere la brevità dell'esempio. + +Dopo aver definito (\texttt{\small 5}) una variabile \var{value} di tipo +\type{sigval\_t} per poter inviare i dati, e dopo aver opportunamente scelto +(\texttt{\small 6}) per \var{signo} un segnale \textit{real-time}, la parte +iniziale del programma (\texttt{\small 8--11}) installa il relativo gestore +(la cui definizione è riportata in fig.~\ref{fig:sig_rtsival_handl}). Dopo di +che il programma si pone in un ciclo infinito (\texttt{\small 14--27}) in cui +prima (\texttt{\small 15--20}) legge in buffer dallo \textit{standard input} +una stringa immessa dall'utente, terminandola opportunamente (\texttt{\small + 20}), e poi tenta di convertire la stessa (\texttt{\small 21}) in un numero +con \func{strtol}, assegnando il risultato a \texttt{value.sival\_int}, se la +conversione ha successo e \texttt{value.sival\_int} è positivo) invia a se +stesso (\texttt{\small 23}) il segnale \textit{real-time}, altrimenti stampa +un avviso (\texttt{\small 24}). + +Alla ricezione del segnale il gestore si limita a stampare alcune delle +informazioni ricevute nella struttura \struct{sigval\_t}, ed in particolare +(\texttt{\small 5}) stampa tramite il valore del campo \var{si\_value} il +numero che gli è stato inviato da \func{sigqueue}. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{\codesamplewidth} + \includecodesample{listati/rtsigvalsend_handl.c} + \end{minipage} + \normalsize + \caption{Codice del gestore usato dal programma di + fig.~\ref{fig:sig_rtsival_main}.} + \label{fig:sig_rtsival_handl} +\end{figure} + \subsection{La gestione avanzata delle temporizzazioni} \label{sec:sig_timer_adv} @@ -3147,20 +3196,6 @@ alta definizione però erano già presenti, essendo stata introdotte insieme ad altre funzioni per il supporto delle estensioni \textit{real-time} con il rilascio del kernel 2.6, ma la risoluzione effettiva era nominale. -A tutte le implementazioni che si rifanno a queste estensioni è richiesto di -disporre di una versione \textit{real-time} almeno per l'orologio generale di -sistema, quello che mantiene il \textit{calendar time} (vedi -sez.~\ref{sec:sys_time_base}), che in questa forma deve indicare il numero di -secondi e nanosecondi passati a partire dal primo gennaio 1970 (\textit{The - Epoch}). Si ricordi infatti che l'orologio ordinario usato dal -\textit{calendar time} riporta solo un numero di secondi, e che la risoluzione -effettiva normalmente non raggiunge il nanosecondo (a meno di hardware -specializzato). Oltre all'orologio generale di sistema possono essere -presenti altri tipi di orologi \textit{real-time}, ciascuno dei quali viene -identificato da un opportuno valore di una variabile di tipo -\type{clockid\_t}; un elenco di quelli disponibili su Linux è riportato in -tab.~\ref{tab:sig_timer_clockid_types}. - \begin{table}[htb] \footnotesize \centering @@ -3218,6 +3253,19 @@ tab.~\ref{tab:sig_timer_clockid_types}. \label{tab:sig_timer_clockid_types} \end{table} +A tutte le implementazioni che si rifanno a queste estensioni è richiesto di +disporre di una versione \textit{real-time} almeno per l'orologio generale di +sistema, quello che mantiene il \textit{calendar time} (vedi +sez.~\ref{sec:sys_time_base}), che in questa forma deve indicare il numero di +secondi e nanosecondi passati a partire dal primo gennaio 1970 (\textit{The + Epoch}). Si ricordi infatti che l'orologio ordinario usato dal +\textit{calendar time} riporta solo un numero di secondi, e che la risoluzione +effettiva normalmente non raggiunge il nanosecondo (a meno di hardware +specializzato). Oltre all'orologio generale di sistema possono essere +presenti altri tipi di orologi \textit{real-time}, ciascuno dei quali viene +identificato da un opportuno valore di una variabile di tipo +\type{clockid\_t}; un elenco di quelli disponibili su Linux è riportato in +tab.~\ref{tab:sig_timer_clockid_types}. % TODO: dal 4.17 CLOCK_MONOTONIC e CLOCK_BOOTTIME sono identici vedi % https://lwn.net/Articles/751651/ e