From: Simone Piccardi Date: Sun, 7 Jul 2002 15:49:37 +0000 (+0000) Subject: Aggiunta select poll e qualche spiegazione X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=36d87df53baa72bedbcb187cddf2ccce5ff79b68;hp=9c6ea14a2d89e1cb76b4dd8683542f71c9dcf107 Aggiunta select poll e qualche spiegazione --- diff --git a/fileadv.tex b/fileadv.tex index 21dc922..067e1ff 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -28,37 +28,79 @@ 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, 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 comportamento causa uno dei problemi più comuni che ci si trova ad +affrontare nelle operazioni di I/O, che è quello che si verifica quando si +devono eseguire operazioni che possono bloccarsi su più file descriptor: +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 +ritardata inutilmente, e nel peggiore si potrebbe addirittura arrivare ad un +deadlock. + +Abbiamo già accennato in \secref{sec:file_open} che però è possibile prevenire questo tipo di comportamento aprendo un file in modalità -\textsl{non-bloccante}, specificando il flag \macro{O\_NONBLOCK} alla chiamata -di \func{open}. In questo caso le funzioni di input/output che altrimenti si -sarebbero bloccate ritornano immediatamente, restituendo l'errore -\macro{EAGAIN}. +\textsl{non-bloccante}, attraverso l'uso del flag \macro{O\_NONBLOCK} nella +chiamata di \func{open}. In questo caso le funzioni di input/output che +altrimenti si sarebbero bloccate ritornano immediatamente, restituendo +l'errore \macro{EAGAIN}. -L'utilizzo di questa modalità di I/O permette allora di risolvere il problema +L'utilizzo di questa modalità di I/O permette di risolvere il problema controllando a turno i vari file descriptor, in un ciclo in cui si ripete l'accesso fintanto che esso non viene garantito. Ovviamente questa tecnica, detta \textit{polling}, è estremamente inefficiente: si tiene costantemente impiegata la CPU solo per eseguire in continuazione delle system call che -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 poterle usare però è comunque comunque -necessario utilizzare la modalità di I/O non bloccante all'apertura del file. +nella gran parte dei casi falliranno. Per evitare questo, come vedremo in +\secref{sec:file_multiplexing}, è stata introdotta una nuova interfaccia di +programmazione, che comporta comunque l'uso della modalità di I/O non +bloccante. \subsection{Le funzioni \func{poll} e \func{select}} \label{sec:file_multiplexing} +Per superare il problema di dover usare il \textit{polling} controllare la +disponibilità di accesso ad un file aperto in modalità non bloccante, sia BSD +che SysV hanno introdotto delle nuove funzioni in grado di sospendere +l'esecuzione di un processo fino a che l'accesso diventi possibile; il primo +ad introdurre questa nuova interfaccia, chiamata usualmente \textit{I/O + multiplexing}, è stato BSD, con l'introduzione della funzione \func{select}, +il cui prototipo è: +\begin{prototype}{sys/select.h} + {int select(int n, fd\_set *readfds, fd\_set *writefds, fd\_set *exceptfds, + struct timeval *timeout)} + +Attende che un certo insieme di file descriptor cambi stato. + +\bodydesc{La funzione restituisce il numero di file descriptor, anche nullo, + che hanno cambiato stato in caso di successo e -1 in caso di errore, nel + qual caso \var{errno} viene settata ai valori: + \begin{errlist} + \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato in uno + degeli insiemi. + \item[\macro{EINTR}] La funzione è stata interrotta da un segnale. + \item[\macro{EINVAL}] Si è specificato per \param{n} un valore negativo. + \end{errlist} + ed inoltre \macro{ENOMEM}. +} +\end{prototype} + +La funzione mette il processo in stato di \textit{sleep} (vedi +\ref{tab:proc_proc_states}) + + + +il cui prototipo è: +\begin{prototype}{sys/poll.h} + {int poll(struct pollfd *ufds, unsigned int nfds, int timeout)} + +La funzione attente un cambiamento di stato per uno dei file descriptor +specificati da \param{ufds}. + +\bodydesc{La funzione restituisce il numero di file descriptor con attività in + caso di successo, o 0 se c'è stato un timeout; in caso di errore viene + restituito -1 ed \var{errno} viene .} +\end{prototype} + + \subsection{L'I/O asincrono}