From: Simone Piccardi Date: Sat, 6 Jul 2002 11:36:07 +0000 (+0000) Subject: Lavoro in treno per webbit X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=9c6ea14a2d89e1cb76b4dd8683542f71c9dcf107;p=gapil.git Lavoro in treno per webbit --- diff --git a/fileadv.tex b/fileadv.tex index 6281f75..21dc922 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -28,13 +28,13 @@ I/O possono bloccarsi indefinitamente.\footnote{si ricordi per esempio le operazioni di lettura possono bloccarsi quando non ci sono dati disponibili sul descrittore su cui si sta operando. -Uno dei problemi più comuni che ci si trova ad affrontare, e che non può -essere risolto con le funzioni base trattate in -\capref{cha:file_unix_interface}, è quello in cui si devono eseguire su più -file descriptor operazioni che possono bloccarsi: il problema è che mentre si -è bloccati su uno di questi file su di un'altro potrebbero essere presenti dei -dati, così che nel migliore dei casi si avrebbe una lettura inutilmente -ritardata, e nel peggiore si potrebbe addirittura arrivare ad un deadlock. +Uno dei problemi più comuni che ci si trova ad affrontare, che non può essere +risolto con le funzioni di base trattate in \capref{cha:file_unix_interface}, +è quello in cui si devono eseguire operazioni che possono bloccarsi su più +file descriptor: il problema è che mentre si è bloccati su uno di questi file +su di un'altro potrebbero essere presenti dei dati, così che nel migliore dei +casi si avrebbe una lettura inutilmente ritardata, e nel peggiore si potrebbe +addirittura arrivare ad un deadlock. Abbiamo già accennato in \secref{sec:file_open} che è possibile prevenire questo tipo di comportamento aprendo un file in modalità @@ -53,18 +53,13 @@ nella gran parte dei casi falliranno. Per questo motivo, quando come vedremo in dettaglio in \secref{sec:file_multiplexing}, il sistema fornisce delle funzioni apposite che permettono di aggirare questo problema, permettendo di attendere fino alla -disponibilità di un accesso; per usarle però è comunque comunque necessario -utilizzare la modalità di I/O non bloccante. +disponibilità di un accesso; per poterle usare però è comunque comunque +necessario utilizzare la modalità di I/O non bloccante all'apertura del file. \subsection{Le funzioni \func{poll} e \func{select}} \label{sec:file_multiplexing} -%\section{I/O asincrono} -%\label{sec:file_asynchronous} - -%Non supportato in Linux, in BSD e SRv4 c'è, ma usando il segnale \macro{SIGIO} -%per indicare che i dati sono disponibili, \subsection{L'I/O asincrono} \label{sec:file_asyncronous_io} @@ -76,16 +71,17 @@ modalit di \func{fcntl}. In tal caso il sistema genera un segnale \macro{SIGIO} tutte le volte che sono -presenti dei dati in input sul file. - - - -Uno dei problemi che si presentavano con le prime implementazioni di questa -modalità di I/O è che essa poteva essere usata in maniera semplice con un solo -file per processo, dato che altrimenti non sarebbe stato distinguere da quale -file provieniva l'attività che ha causato l'emissione del segnale. - - +presenti dei dati in input su un file aperto in questa modalità. Uno dei +problemi che si presentavano con le prime implementazioni di questa modalità +di I/O è che essa poteva essere usata in maniera semplice aprendo un solo file +per processo, dato che altrimenti si sarebbe dovuto provvedere ad effettuare +una serie di controlli su tutti i file aperti per distinguere a quale fosse +dovuto l'emissione del segnale. + +Tutto questo adesso può essere evitato facendo ricorso alle informazioni +restituite al manipolatore del segnale attraverso la struttura +\var{siginfo\_t} (vedi \figref{fig:sig_siginfo_t}), il cui campo \var{si\_fd} +riporta il file descriptor che ha generato il segnale. diff --git a/signal.tex b/signal.tex index 4a81828..246c308 100644 --- a/signal.tex +++ b/signal.tex @@ -16,7 +16,7 @@ In questo capitolo esamineremo i vari aspetti della gestione dei segnali, partendo da una introduzione relativa ai concetti base con cui essi vengono realizzati, per poi affrontarne la classificazione a secondo di uso e modalità di generazione fino ad esaminare in dettaglio funzioni e le metodologie di -gestione. +gestione. \section{Introduzione} @@ -1795,52 +1795,6 @@ struct sigaction \label{fig:sig_sigaction} \end{figure} -Come si può notare da quanto riportato in \figref{fig:sig_sigaction} in Linux -\func{sigaction} permette di specificare il manipolatore in due forme diverse, -indicate dai campi \var{sa\_handler} e \var{sa\_sigaction}; esse devono essere -usate in maniera alternativa (in certe implementazioni questi vengono -specificati 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}. - -\begin{figure}[!htb] - \footnotesize \centering - \begin{minipage}[c]{15cm} - \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} -siginfo_t { - int si_signo; /* Signal number */ - int si_errno; /* An errno value */ - int si_code; /* Signal code */ - pid_t si_pid; /* Sending process ID */ - uid_t si_uid; /* Real user ID of sending process */ - int si_status; /* Exit value or signal */ - clock_t si_utime; /* User time consumed */ - clock_t si_stime; /* System time consumed */ - sigval_t si_value; /* Signal value */ - int si_int; /* POSIX.1b signal */ - void * si_ptr; /* POSIX.1b signal */ - void * si_addr; /* Memory location which caused fault */ - int si_band; /* Band event */ - int si_fd; /* File descriptor */ -} - \end{lstlisting} - \end{minipage} - \normalsize - \caption{La struttura \var{siginfo\_t}.} - \label{fig:sig_siginfo_t} -\end{figure} - -Installando un manipolatore di tipo \var{sa\_sigaction} diventa allora -possibile accedere al risultato restituito attraverso il puntatore a questa -struttura. Tutti i segnali settano i campi \var{si\_signo}, \var{si\_errno} e -\var{si\_code}, ed il resto della struttura può essere definito come -\ctyp{union} ed i valori eventualmente presenti dipendono dal segnale (ad -esempio può essere il tipo di errore nel caso di \macro{SIGFPE}); vedremo un -esempio di tutto ciò per \macro{SIGIO} in \secref{sec:file_asyncronous_io}, -per i dettagli degli altri segnali si consulti la man page di -\func{sigaction}). - Il campo \var{sa\_mask} serve ad indicare l'insieme dei segnali che devono essere bloccati durante l'esecuzione del manipolatore, ad essi viene comunque sempre aggiunto il segnale che ne ha causato la chiamata, a meno che non si @@ -1897,6 +1851,68 @@ in \tabref{tab:sig_sa_flag}. \label{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}. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} +siginfo_t { + int si_signo; /* Signal number */ + int si_errno; /* An errno value */ + int si_code; /* Signal code */ + pid_t si_pid; /* Sending process ID */ + uid_t si_uid; /* Real user ID of sending process */ + int si_status; /* Exit value or signal */ + clock_t si_utime; /* User time consumed */ + clock_t si_stime; /* System time consumed */ + sigval_t si_value; /* Signal value */ + int si_int; /* POSIX.1b signal */ + void * si_ptr; /* POSIX.1b signal */ + void * si_addr; /* Memory location which caused fault */ + int si_band; /* Band event */ + int si_fd; /* File descriptor */ +} + \end{lstlisting} + \end{minipage} + \normalsize + \caption{La struttura \var{siginfo\_t}.} + \label{fig:sig_siginfo_t} +\end{figure} + +Installando un manipolatore di tipo \var{sa\_sigaction} diventa allora +possibile accedere alle informazioni restituite attraverso il puntatore a +questa struttura. Tutti i segnali settano i campi \var{si\_signo}, che riporta +il segnale ricevuto, \var{si\_errno}, che riporta il codice di errore, e +\var{si\_code}, che viene usato per indicare la ragione per cui è stato emesso +il segnale (come i dettagli sul tipo di errore per \macro{SIGFPE} e +\macro{SIGILL}) ed ha valori diversi\footnote{un elenco dettagliato è + disponibile nella man page di \func{sigaction}.} a seconda del tipo di +segnale ricevuto. + +Il resto della struttura può essere definito come \ctyp{union} ed i valori +eventualmente presenti dipendono dal segnale, così \macro{SIGCHLD} ed i +segnali POSIX.1b\footnote{NdA trovare quale sono e completare l'informazione.} +inviati tramite \func{kill} avvalorano \var{si\_pid} e \var{si\_uid} coi +valori corrispondenti al processo che ha emesso il segnale, \macro{SIGILL}, +\macro{SIGFPE}, \macro{SIGSEGV} e \macro{SIGBUS} avvalorano \var{si\_addr} con +l'indirizzo cui è avvenuto l'errore, \macro{SIGIO} (vedi +\secref{sec:file_asyncronous_io}) e \macro{SIGPOLL} avvalorano \var{si\_fd} +con il numero del file descriptor. + Benché sia possibile usare nello stesso programma sia \func{sigaction} che \func{signal} occorre molta attenzione, in quanto le due funzioni possono interagire in maniera anomala. Infatti l'azione specificata con @@ -1910,16 +1926,9 @@ Per questo ripristinare correttamente un manipolatore precedente, anche se questo è stato installato con \func{signal}. In generale poi non è il caso di usare il valore di ritorno di \func{signal} come campo \var{sa\_handler}, o viceversa, dato -che in certi sistemi questi possono essere diversi. In generale dunque, a meno -che non si sia vincolati allo standard ISO C, è sempre il caso di evitare -l'uso di \func{signal} a favore di \func{sigaction}. - -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 come \code{inline} nel file \file{wrapper.h} (nei sorgenti -allegati), riportata in \figref{fig:sig_Signal_code}. La riutilizzeremo spesso -in seguito. +che in certi sistemi questi possono essere diversi. In definitiva dunque, a +meno che non si sia vincolati all'aderenza stretta allo standard ISO C, è +sempre il caso di evitare l'uso di \func{signal} a favore di \func{sigaction}. \begin{figure}[!htb] \footnotesize \centering @@ -1951,6 +1960,13 @@ inline SigFunc * Signal(int signo, SigFunc *func) \label{fig:sig_Signal_code} \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 come \code{inline} nel file \file{wrapper.h} (nei sorgenti +allegati), riportata in \figref{fig:sig_Signal_code}. La riutilizzeremo spesso +in seguito. + \subsection{La gestione della \textsl{maschera dei segnali} o \textit{signal mask}} \label{sec:sig_sigmask}