X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=signal.tex;h=177555d272f2a7d13a1e15019b3969916185d886;hb=0bcf5c7d8d90342067fe6cb28045993bf6c7f207;hp=e4aaa11b885a5d043919f6297923911f806d2c29;hpb=a2af189773dd33845c8690e588b46a7d12ff7ec0;p=gapil.git diff --git a/signal.tex b/signal.tex index e4aaa11..177555d 100644 --- a/signal.tex +++ b/signal.tex @@ -865,6 +865,9 @@ sez.~\ref{sec:sig_sigaction}). interruzione nel mezzo di un trasferimento parziale di dati, le system call ritornano sempre indicando i byte trasferiti. +% TODO: alcune syscall danno EINTR anche se il segnale è installato con +% SA_RESTART, vedi signal(7) + \subsection{La funzione \func{signal}} \label{sec:sig_signal} @@ -1988,7 +1991,9 @@ rispettivamente lo stato di uscita, l'\textit{user time} e il \textit{system \var{si\_addr} con l'indirizzo in cui è avvenuto l'errore, \const{SIGIO} (vedi sez.~\ref{sec:file_asyncronous_io}) avvalora \var{si\_fd} con il numero del file descriptor e \var{si\_band} per i \itindex{out-of-band} dati urgenti -(vedi sez.~\ref{sec:TCP_urgent_data}) su un socket. +(vedi sez.~\ref{sec:TCP_urgent_data}) su un socket, il segnale inviato alla +scadenza di un timer POSIX (vedi sez.~\ref{sec:sig_timer_adv}) avvalora i +campi \var{si\_timerid} e \var{si\_overrun}. Benché sia possibile usare nello stesso programma sia \func{sigaction} che \func{signal} occorre molta attenzione, in quanto le due funzioni possono @@ -2668,6 +2673,9 @@ sostituito dalla risorsa \const{RLIMIT\_SIGPENDING} associata al singolo utente, che può essere modificata con \func{setrlimit} come illustrato in sez.~\ref{sec:sys_resource_limit}. +% TODO: spostare insieme a signalfd e affini, meccanismo di notifica sincrona +% dei segnali (da capire se è il caso di farlo) + Lo standard POSIX.1b definisce inoltre delle nuove funzioni che permettono di gestire l'attesa di segnali specifici su una coda, esse servono in particolar modo nel caso dei \itindex{thread} \textit{thread}, in cui si possono usare i @@ -3179,7 +3187,7 @@ segnale \textit{real-time} per ciascun timer che viene creato con \func{timer\_create}; dato che ciascuno di essi richiede un posto nella coda dei segnali \textit{real-time}, il numero massimo di timer utilizzabili da un processo è limitato dalle dimensioni di detta coda, ed anche, qualora questo -sia stato impostato, dal limite \const{RLIMIT\_SIGPENDING} +sia stato impostato, dal limite \const{RLIMIT\_SIGPENDING}. Una volta creato il timer \func{timer\_create} ed ottenuto il relativo identificatore, si può attivare o disattivare un allarme (in gergo @@ -3250,7 +3258,8 @@ impostare un allarme periodico. Se il suo valore tutti e due i valori di detta struttura \struct{timespec}) l'allarme scatterà una sola volta secondo quando indicato con \var{it\_value}, altrimenti il valore specificato verrà preso come l'estensione del periodo di ripetizione -della generazione dell'allarme. +della generazione dell'allarme, che proseguirà indefinitamente fintanto che +non si disarmi il timer. Se il timer era già stato armato la funzione sovrascrive la precedente impostazione, se invece si indica come prima scadenza un tempo già passato, @@ -3297,9 +3306,12 @@ nullo se non ve ne sono state. Come estensione specifica di Linux,\footnote{in segnali e non ne parla affatto in riferimento ai \textit{thread}.} quando si usa un segnale come meccanismo di notifica, si può ottenere direttamente questo valore nel campo \var{si\_overrun} della struttura \struct{siginfo\_t} -restituita al gestore del segnale installato con \func{sigaction}, in questo -modo non è più necessario eseguire successivamente una chiamata a questa -funzione. +(illustrata in fig.~\ref{fig:sig_siginfo_t}) restituita al gestore del segnale +installato con \func{sigaction}; in questo modo non è più necessario eseguire +successivamente una chiamata a questa funzione per ottenere il numero delle +scadenze. Al gestore del segnale viene anche restituito, come ulteriore +informazione, l'identificativo del timer, in questo caso nel campo +\var{si\_timerid}. Qualora si voglia rileggere lo stato corrente di un timer, ed ottenere il tempo mancante ad una sua eventuale scadenza, si deve utilizzare la funzione @@ -3337,10 +3349,10 @@ impostato per una ripetizione e doveva operare, come suol dirsi, a colpo singolo (in gergo \textit{one shot}). Infine, quando un timer non viene più utilizzato, lo si può cancellare, -rimuovendolo dal sistema e recuperando le relative risorse, eseguendo -l'operazione inversa rispetto a \funcd{timer\_create}. Per questo compito lo -standard prevede una apposita funzione \funcd{timer\_delete}, il cui prototipo -è: +rimuovendolo dal sistema e recuperando le relative risorse, effettuando in +sostanza l'operazione inversa rispetto a \funcd{timer\_create}. Per questo +compito lo standard prevede una apposita funzione \funcd{timer\_delete}, il +cui prototipo è: \begin{functions} \headdecl{time.h} @@ -3350,16 +3362,16 @@ standard prevede una apposita funzione \funcd{timer\_delete}, il cui prototipo \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei seguenti valori: - \begin{errlist} - \item[\errcode{EINVAL}] \param{timerid} non indica un timer valido. - \end{errlist} + \begin{errlist} + \item[\errcode{EINVAL}] \param{timerid} non indica un timer valido. + \end{errlist} } \end{functions} - -% TODO trattare i Posix timer, e le funzioni: -% timer_delete - +La funzione elimina il timer identificato da \param{timerid}, disarmandolo se +questo era stato attivato. Nel caso, poco probabile ma comunque possibile, che +un timer venga cancellato prima della ricezione del segnale pendente per la +notifica di una scadenza, il comportamento del sistema è indefinito. @@ -3367,15 +3379,37 @@ standard prevede una apposita funzione \funcd{timer\_delete}, il cui prototipo \label{sec:sig_signalfd_eventfd} I segnali sono uno dei meccanismi classici, presenti da sempre nei sistemi -unix-like, per effettuare notifiche ai processi, la loro interfaccia però si è -dimostrata quasi subito poco azzeccata, in particolare per i problemi che si -vengono a creare con le funzioni di gestione dell'I/O multiplexing (vedi -sez.~\ref{sec:file_multiplexing}).\footnote{i temi trattati in questa sezione - presuppongono la conoscenza dell'I/O multiplexing si consiglia pertanto una - lettura di sez.~\ref{sec:file_multiplexing} qualora non si conosca - l'argomento. } Per questo motivo nello sviluppo del kernel si è pensato di -introdurre un meccanismo alternativo per la notifica dei segnali (ed anche di -eventi generici) basato direttamente sull'uso di file descriptor. +unix-like, per effettuare notifiche ai processi, la loro interfaccia però, +richiedendo l'esecuzione asincrona di una funzione di gestione al di fuori del +flusso di esecuzione principale del processo, si è dimostrata quasi subito +assai problematica. + +Oltre ai limiti relativi a cosa si può fare nel gestore di segnali (quelli +illustrati in sez.~\ref{sec:sig_signal_handler}), ed ai problemi relativi alla +interruzione delle system call bloccanti, c'è un problema più generale +consistente nel fatto che questa modalità di funzionamento cozza con le +interfacce di programmazione sincrona, in cui ci si aspetta che ci sia un solo +processo che gestisce gli eventi e genera delle risposte, mentre con l'arrivo +di un segnale ci si trova alla possibilità di interruzioni asincrone da +gestire e nella necessità di evitare \textit{race conditions}. + +In particolare, come vedremo in sez.~\ref{sec:file_select}, i segnali hanno +una pessima interazione con le funzioni di gestione dell'I/O multiplexing, che +costituiscono un meccanismo efficiente per gestire in maniera sincrona +l'accesso a più file o socket in cui il processo si blocca fintanto che non ci +sono dati da leggere o scrivere.\footnote{per la trattazione dettagliata del + significato e dei vantaggi dell'I/O multiplexing si rimanda a + sez.~\ref{sec:file_multiplexing}.} + +Abbiamo visto in sez.~\ref{sec:sig_real_time} che con i segnali +\textit{real-time} sono state introdotte delle interfacce di gestione sincrona +dei segnali con \func{sigwait} e affini, che consentono di gestire i segnali +in modalità sincrona, bloccando un processo fino alla ricezione di un segnale +(e disabilitando l'esecuzione asincrona di un gestore). Questo però non +risolve i problemi di interazioni con le funzioni I/O multiplexing per cui +nello sviluppo del kernel si è pensato di introdurre un meccanismo alternativo +per la notifica dei segnali (ed anche di eventi generici) basato direttamente +sull'uso di file descriptor. @@ -3443,7 +3477,7 @@ eventi generici) basato direttamente sull'uso di file descriptor. % LocalWords: resolution CONFIG RES patch REALTIME MONOTONIC RAW NTP CPUTIME % LocalWords: tick calendar The Epoch list getcpuclockid capability CAP getres % LocalWords: ENOSYS pthread ENOENT NULL attribute itimerspec new old ABSTIME -% LocalWords: epoch multiplexing +% LocalWords: epoch multiplexing overrun %%% Local Variables: