From: Simone Piccardi Date: Fri, 12 Jul 2002 16:56:35 +0000 (+0000) Subject: Riscritta (meglio) select X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=44ef16d86264e295b1987168b99aed3190753b3e;p=gapil.git Riscritta (meglio) select --- diff --git a/fileadv.tex b/fileadv.tex index b376483..7b3a6b1 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -53,25 +53,30 @@ nella gran parte dei casi falliranno. Per evitare questo, come vedremo in 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 System V 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 è: +Per superare il problema di dover usare il \textit{polling} per controllare la +possibilità di effettuare operazioni su un file aperto in modalità non +bloccante, sia BSD che System V hanno introdotto delle nuove funzioni in grado +di sospendere l'esecuzione di un processo in attesa che l'accesso diventi +possibile. Il primo ad introdurre questa modalità di operazione, chiamata +usualmente \textit{I/O multiplexing}, è stato BSD,\footnote{la funzione è + apparsa in BSD4.2 e standardizzata in BSD4.4, ma è stata portata su tutti i + sistemi che supportano i \textit{socket}, compreso le varianti di System V.} +con la 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: + Attende che uno dei file descriptor degli insiemi specificati diventi + attivo. + + \bodydesc{La funzione in caso di successo restituisce il numero di file + descriptor (anche nullo) che sono attivi, 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 degli insiemi. @@ -83,17 +88,18 @@ Attende che un certo insieme di file descriptor cambi stato. \end{prototype} La funzione mette il processo in stato di \textit{sleep} (vedi -\tabref{tab:proc_proc_states}) fintanto che non viene rilevate dell'attività -sull'insieme dei file descriptor specificati (\param{readfds}, -\param{writefds} e \param{exceptfds}), per un tempo massimo specificato da -\param{timeout}. - -Per specificare quali file descriptor si intende selezionare, la funzione usa -un particolare oggetto, il \textit{file descriptor set}, identificato dal tipo -\type{fd\_set}, che serve ad identificare un insieme di file descriptor, in -maniera analoga a come un \textit{signal set} (vedi \secref{sec:sig_sigset}) -identifica un insieme di segnali. Per la manipolazione di questi \textit{file - descriptor set} si possono usare delle opportune macro di preprocessore: +\tabref{tab:proc_proc_states}) fintanto che almeno uno dei file descriptor +degli insiemo specificati (\param{readfds}, \param{writefds} e +\param{exceptfds}), non diventa attivo, per un tempo massimo specificato da +\param{timeout}. + +Per specificare quali file descriptor si intende \textsl{selezionare}, la +funzione usa un particolare oggetto, il \textit{file descriptor set}, +identificato dal tipo \type{fd\_set}, che serve ad identificare un insieme di +file descriptor, (in maniera analoga a come un \textit{signal set}, vedi +\secref{sec:sig_sigset}, identifica un insieme di segnali). Per la +manipolazione di questi \textit{file descriptor set} si possono usare delle +opportune macro di preprocessore: \begin{functions} \headdecl{sys/select.h} \funcdecl{FD\_ZERO(fd\_set *set)} @@ -110,28 +116,53 @@ identifica un insieme di segnali. Per la manipolazione di questi \textit{file \end{functions} In genere un \textit{file descriptor set} può contenere fino ad un massimo di -\macro{FD\_SETSIZE} file descriptor. Questo a seconda del sistema può essere -il limite del numero massimo di file aperti\footnote{ad esempio in Linux, fino - alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma quando, -come nelle versioni più recenti del kernel, questo limite non c'è un massimo, -esso indica le dimensioni in numero di bit utilizzabili per l'insieme. +\macro{FD\_SETSIZE} file descriptor. Questo valore in origine corrispondeva +al limite per il numero massimo di file aperti\footnote{ad esempio in Linux, + fino alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma +quando, come nelle versioni più recenti del kernel, non c'è più un limite +massimo, esso indica le dimensioni massime dei numeri usati nei \textit{file + descriptor set}. La funzione richiede di specificare tre insiemi distinti di file descriptor; il primo, \param{readfds}, verrà osservato per rilevare la disponibilità di -input in lettura, il secondo, \param{writefds} per verificare la possibilità -di scrivere ed il terzo, \param{exceptfds}, per verificare l'esistenza di -eccezioni. I corrispondenti valori dei \textit{file descriptor set} saranno -modificati di conseguenza per mostrare quale dei file descriptor ha cambiato -stato. - - - - - -Come accennato l'interfaccia di \func{select} è una estensione aggiunta BSD, e -poi entrata a far parte di POSIX; allo stesso tempo System V aveva introdotto -una interfaccia alternativa, basata sulla funzione \func{poll}, il cui -prototipo è: +effettuare una lettura, il secondo, \param{writefds}, per verificare la +possibilità effettuare una scrittura ed il terzo, \param{exceptfds}, per +verificare l'esistenza di condizioni eccezionali (come i messaggi urgenti su +un \textit{socket}\index{socket}, vedi \secref{sec:xxx_urgent}). + +La funzione inoltre richiede anche di specificare, tramite l'argomento +\param{n}, un valore massimo del numero dei file descriptor usati +nell'insieme; si può usare il già citato \macro{FD\_SETSIZE}, oppure il numero +più alto dei file descriptor usati nei tre insiemi, aumentato di uno. + +Infine l'argomento \param{timeout}, specifica un tempo massimo di +attesa\footnote{il tempo è valutato come \textit{elapsed time}.} prima che la +funzione ritorni; se settato a \macro{NULL} la funzione attende +indefinitamente. Si può specificare anche un tempo nullo (cioè una \var{struct + timeval} con i campi settati a zero), qualora si voglia semplicemente +controllare lo stato corrente dei file descriptor. + +La funzione restituisce il totale dei file descriptor pronti nei tre insiemi, +il valore zero indica sempre che si è raggiunto un timeout. Ciascuno dei tre +insiemi viene sovrascritto per indicare quale file descriptor è pronto per le +operazioni ad esso relative, in modo da poterlo controllare con la macro +\macro{FD\_ISSET}. In caso di errore la funzione restituisce -1 e gli insiemi +non vengono toccati. + +In Linux \func{select} modifica anche il valore di \param{timeout}, settandolo +al tempo restante; questo è utile quando la funzione viene interrotta da un +segnale, in tal caso infatti si ha un errore di \macro{EINTR}, ed occorre +rilanciare la funzione; in questo modo non è necessario ricalcolare tutte le +volte il tempo rimanente.\footnote{questo però può causare problemi di + portabilità sia quando si trasporta codice scritto su Linux che legge questo + valore, sia quando si usano programmi scritti per altri sistemi che non + dispongono di questa caratteristica e ricalcolano \param{timeout} tutte le + volte. In genere la caratteristica è disponibile nei sistemi che derivano da + System V e non disponibile per quelli che derivano da BSD.} + +Come accennato l'interfaccia di \func{select} è una estensione di BSD; anche +System V ha introdotto una sua interfaccia per getire l'\textit{I/O + multiplexing}, basata sulla funzione \func{poll}, il cui prototipo è: \begin{prototype}{sys/poll.h} {int poll(struct pollfd *ufds, unsigned int nfds, int timeout)} @@ -141,13 +172,16 @@ 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 settata ai valori: - -.} + \begin{errlist} + \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato in uno + degli insiemi. + \item[\macro{EINTR}] La funzione è stata interrotta da un segnale. + \end{errlist} + ed inoltre \macro{EFAULT} e \macro{ENOMEM}.} \end{prototype} - \subsection{L'I/O asincrono} \label{sec:file_asyncronous_io} diff --git a/gapil.tex b/gapil.tex index 6765ae5..2326d68 100644 --- a/gapil.tex +++ b/gapil.tex @@ -21,8 +21,8 @@ \usepackage{listings} \lstloadlanguages{C++} \usepackage{color} -%\usepackage{mdwlist} % scommentare per la stampa (PS e PDF) -%\usepackage{boxedminipage} % scommentare per la stampa (PS e PDF) +\usepackage{mdwlist} % scommentare per la stampa (PS e PDF) +\usepackage{boxedminipage} % scommentare per la stampa (PS e PDF) %\usepackage{footnote} %\usepackage{mdwtab} % @@ -73,7 +73,7 @@ \tableofcontents \clearemptydoublepage -\include{compatib} % commentare per la stampa PS e PDF +%\include{compatib} % commentare per la stampa PS e PDF \include{macro} \setcounter{secnumdepth}{-2}