Altre modifiche che mi ero dimenticato di buttar giu ieri
authorSimone Piccardi <piccardi@gnulinux.it>
Mon, 5 Jan 2004 19:24:52 +0000 (19:24 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Mon, 5 Jan 2004 19:24:52 +0000 (19:24 +0000)
fileadv.tex
sources/poll_echod.c
tcpsockadv.tex

index a4f8229095c3ccb4dc5ab7a272330072dca3c446..f343a48fba02af45a22bec250db84cb6ed64b5c8 100644 (file)
@@ -306,12 +306,12 @@ interruzione si potranno eseguire le relative operazioni.
 \subsection{La funzione \func{poll}}
 \label{sec:file_poll}
 
-System V, invece di utilizzare l'interfaccia di \func{select}, che è una
-estensione creata nello sviluppo di BSD, ha introdotto una sua interfaccia per
-gestire l'\textit{I/O multiplexing}, basata sulla funzione
-\funcd{poll},\footnote{la funzione è prevista dallo standard XPG4, ed è stata
-  introdotta in Linux come system call a partire dal kernel 2.1.23 ed inserita
-  nelle \acr{libc} 5.4.28.} il cui prototipo è:
+Nello sviluppo di System V, invece di utilizzare l'interfaccia di
+\func{select}, che è una estensione tipica di BSD, è stata introdotta un'altra
+interfaccia, basata sulla funzione \funcd{poll},\footnote{la funzione è
+  prevista dallo standard XPG4, ed è stata introdotta in Linux come system
+  call a partire dal kernel 2.1.23 ed inserita nelle \acr{libc} 5.4.28.} il
+cui prototipo è:
 \begin{prototype}{sys/poll.h}
   {int poll(struct pollfd *ufds, unsigned int nfds, int timeout)}
   
@@ -331,13 +331,14 @@ gestire l'\textit{I/O multiplexing}, basata sulla funzione
   ed inoltre \errval{EFAULT} e \errval{ENOMEM}.}
 \end{prototype}
 
-La funzione permette di tenere sotto controllo un certo numero \param{ndfs} di
-file descriptor, specificati attraverso un vettore di puntatori a strutture
-\struct{pollfd}.  Come \func{select} anche \func{poll} permette di
-interrompere l'attesa dopo un certo tempo, che va specificato attraverso
+La funzione permette di tenere sotto controllo contemporaneamente \param{ndfs}
+file descriptor, specificati attraverso il puntatore \param{ufds} ad un
+vettore di strutture \struct{pollfd}.  Come con \func{select} si può
+interrompere l'attesa dopo un certo tempo, questo deve essere specificato con
 l'argomento \param{timeout} in numero di millisecondi: un valore negativo
-indica un'attesa indefinita mentre si può usare un valore nullo per eseguire
-la funzione in modalità \textsl{non-bloccante}.
+indica un'attesa indefinita, mentre un valore comporta il ritorno immediato (e
+può essere utilizzato per impiegare \func{poll} in modalità
+\textsl{non-bloccante}).
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -350,15 +351,18 @@ la funzione in modalit
   \label{fig:file_pollfd}
 \end{figure}
 
-Per ciascun file da controllare deve essere opportunamente predisposta una
-struttura \struct{pollfd}, la cui definizione è riportata in
-\figref{fig:file_pollfd}.  La struttura prevede tre campi: il campo \var{fd}
-viene utilizzato per specificare il file descriptor relativo al file da
-controllare, mentre nel campo \var{events} deve essere specificata una
-maschera binaria data in ingresso che indichi il tipo di evento che si vuole
-controllare, il kernel restituirà il relativo risultato nel campo
-\var{revents}.  Usando un valore negativo per \param{fd} la corrispondente
-struttura sarà ignorata da \func{poll}.
+Per ciascun file da controllare deve essere inizializzata una struttura
+\struct{pollfd} nel vettore indicato dall'argomento \param{ufds}.  La
+struttura, la cui definizione è riportata in \figref{fig:file_pollfd}, prevede
+tre campi: in \var{fd} deve essere indicato il numero del file descriptor da
+controllare, in \var{events} deve essere specificata una maschera binaria di
+flag che indichino il tipo di evento che si vuole controllare, mentre in
+\var{revents} il kernel restituirà il relativo risultato.  Usando un valore
+negativo per \param{fd} la corrispondente struttura sarà ignorata da
+\func{poll}. Dato che i dati in ingresso sono del tutto indipendenti da quelli
+in uscita (che vengono restituiti in \var{revents}) non è necessario
+reinizializzare tutte le volte il valore delle strutture \struct{pollfd} a
+meno di non voler cambiare qualche condizione.
 
 Le costanti che definiscono i valori relativi ai bit usati nelle maschere
 binarie dei campi \var{events} e \var{revents} sono riportati in
@@ -397,18 +401,22 @@ nel campo \var{revents} per notificare delle condizioni di errore.
   \label{tab:file_pollfd_flags}
 \end{table}
 
-Infine il valore \const{POLLMSG} non viene utilizzato ed è definito solo per
-compatibilità con l'implementazione di SysV, dove indica segnale
-\const{SIGPOLL} è arrivato alla cima dello \textit{stream}. Gli
-\textit{stream} sono una interfaccia specifica di SysV non presente in Linux,
-e non hanno nulla a che fare con i file \textit{stream} delle librerie
-standard del C, è da questi che derivano i nomi delle costanti, in quanto per
-essi sono definite tre classi di dati: \textsl{normali}, \textit{prioritari}
-ed \textit{urgenti}. Nel caso di Linux la distinzione ha senso solo nel caso
-per i dati \textit{out-of-band} dei socket (vedi
+Il valore \const{POLLMSG} non viene utilizzato ed è definito solo per
+compatibilità con l'implementazione di SysV che usa gli
+\textit{stream};\footnote{essi sono una interfaccia specifica di SysV non
+  presente in Linux, e non hanno nulla a che fare con i file \textit{stream}
+  delle librerie standard del C.} è da questi che derivano i nomi di alcune
+costanti, in quanto per essi sono definite tre classi di dati:
+\textsl{normali}, \textit{prioritari} ed \textit{urgenti}.}  In Linux la
+distinzione ha senso solo per i dati \textit{out-of-band} dei socket (vedi
 \secref{sec:TCP_urgent_data}), ma su questo e su come \func{poll} reagisce
 alle varie condizioni dei socket torneremo in \secref{sec:TCP_serv_poll}, dove
-vedremo anche un esempio del suo utilizzo.
+vedremo anche un esempio del suo utilizzo. Si tenga conto comunque che le
+costanti relative ai diversi tipi di dati (come \macro{POLLRDNORM} e
+\macro{POLLRDBAND}) sono utilizzabili soltanto qualora si sia definito
+\macro{\_XOPEN\_SOURCE}.\footnote{e ci si ricordi di farlo sempre in testa al
+  file, definirla soltanto prima di includere \file{sys/poll.h} non è
+  sufficiente.}
 
 In caso di successo funzione ritorna restituendo il numero di file (un valore
 positivo) per i quali si è verificata una delle condizioni di attesa richieste
@@ -423,8 +431,7 @@ tramite \var{errno}.
 %\label{sec:file_epoll}
 % placeholder ...
 
-
-
+%da fare
 
 \section{Altre modalità e funzioni di I/O avanzato}
 \label{sec:file_advanced_io}
@@ -437,16 +444,16 @@ problematiche avanzate riguardanti l'I/O su file, tratteremo tutto ci
 questa sezione.
 
 
-\subsection{L'I/O asincrono}
-\label{sec:file_asyncronous_io}
+\subsection{L'apertura asincrona dei file}
+\label{sec:file_asyncronous_open}
 
-Una modalità alternativa all'uso dell'\textit{I/O multiplexing} è quella di
-fare ricorso al cosiddetto \textsl{I/O asincrono}. Il concetto base
-dell'\textsl{I/O asincrono} è che le funzioni di I/O non attendono il
-completamento delle operazioni prima di ritornare, così che il processo non
-viene bloccato.  In questo modo diventa ad esempio possibile effettuare una
-richiesta preventiva di dati, in modo da poter effettuare in contemporanea le
-operazioni di calcolo e quelle di I/O.
+Una modalità alternativa all'uso dell'\textit{I/O multiplexing} per gestione
+dell'I/O simultaneo su molti file, è costituita dal cosiddetto \textsl{I/O
+  asincrono}. Il concetto base dell'\textsl{I/O asincrono} è che le funzioni
+di I/O non attendono il completamento delle operazioni prima di ritornare,
+così che il processo non viene bloccato.  In questo modo diventa ad esempio
+possibile effettuare una richiesta preventiva di dati, in modo da poter
+effettuare in contemporanea le operazioni di calcolo e quelle di I/O.
 
 Abbiamo accennato in \secref{sec:file_open} che è possibile, attraverso l'uso
 del flag \const{O\_ASYNC},\footnote{l'uso del flag di \const{O\_ASYNC} e dei
@@ -454,19 +461,23 @@ del flag \const{O\_ASYNC},\footnote{l'uso del flag di \const{O\_ASYNC} e dei
   di Linux e BSD.} aprire un file in modalità asincrona, così come è possibile
 attivare in un secondo tempo questa modalità impostando questo flag attraverso
 l'uso di \func{fcntl} con il comando \const{F\_SETFL} (vedi
-\secref{sec:file_fcntl}).
-
-In realtà in questo caso non si tratta di I/O asincrono vero e proprio, quanto
-di un meccanismo asincrono di notifica delle variazione dello stato del file
-descriptor; quello che succede è che il sistema genera un segnale (normalmente
-\const{SIGIO}, ma è possibile usarne altri) tutte le volte che diventa
-possibile leggere o scrivere dal file descriptor che si è posto in questa
-modalità. Si può inoltre selezionare, con il comando \const{F\_SETOWN} di
-\func{fcntl}, quale processo (o gruppo di processi) riceverà il segnale. 
+\secref{sec:file_fcntl}). 
+
+In realtà in questo caso non si tratta di I/O asincrono vero e proprio (che
+vedremo in \secref{sec:file_asyncronous_io}), quanto di un meccanismo
+asincrono di notifica delle variazione dello stato del file descriptor; quello
+che succede è che il sistema genera un segnale (normalmente \const{SIGIO}, ma
+è possibile usarne altri) tutte le volte che diventa possibile leggere o
+scrivere dal file descriptor che si è posto in questa modalità. Si può inoltre
+selezionare, con il comando \const{F\_SETOWN} di \func{fcntl}, quale processo
+(o gruppo di processi) riceverà il segnale. Se pertanto si effettuano le
+operazioni in risposta alla ricezione del segnale non ci sarà più la necessità
+di restare bloccati in attesa della disponibilità di accesso ai file.
 
 In questo modo si può evitare l'uso delle funzioni \func{poll} o \func{select}
 che, quando vengono usate con un numero molto grande di file descriptor, non
-hanno buone prestazioni. In tal caso infatti la maggior parte del loro tempo
+hanno buone prestazioni. % aggiungere cenno a epoll quando l'avrò scritta
+ In tal caso infatti la maggior parte del loro tempo
 di esecuzione è impegnato ad eseguire una scansione su tutti i file descriptor
 tenuti sotto controllo per determinare quali di essi (in genere una piccola
 percentuale) sono diventati attivi.
@@ -503,6 +514,9 @@ invier
 in eccesso, e si dovrà determinare al solito modo quali sono i file diventati
 attivi.
 
+\subsection{L'interfaccia POSIX per l'I/O asincrono}
+\label{sec:file_asyncronous_io}
+
 Benché la modalità di apertura asincrona di un file possa risultare utile in
 varie occasioni (in particolar modo con i socket\index{socket} e gli altri
 file per i quali le funzioni di I/O sono system call lente), essa è comunque
@@ -580,7 +594,7 @@ che serve a specificare il modo in cui si vuole che venga effettuata la
 notifica del completamento delle operazioni richieste. La struttura è
 riportata in \secref{fig:file_sigevent}; il campo \var{sigev\_notify} è quello
 che indica le modalità della notifica, esso può assumere i tre valori:
-\begin{basedescript}{\desclabelwidth{3.0cm}}
+\begin{basedescript}{\desclabelwidth{2.6cm}}
 \item[\const{SIGEV\_NONE}]  Non viene inviata nessuna notifica.
 \item[\const{SIGEV\_SIGNAL}] La notifica viene effettuata inviando al processo
   chiamante il segnale specificato da \var{sigev\_signo}; se il gestore di
index bf2774e83c67e8180a8ec4bbed306919b1538823..9abccf4c58d0cb56b2ff01d122c32487ef598e25 100644 (file)
  *
  * Usage: echod -h give all info
  *
- * $Id: poll_echod.c,v 1.1 2004/01/02 21:32:08 piccardi Exp $
+ * $Id: poll_echod.c,v 1.2 2004/01/05 19:24:52 piccardi Exp $
  *
  ****************************************************************/
 /* 
  * Include needed headers
  */
+#define _XOPEN_SOURCE
 #include <limits.h>      /* system limits */
 #include <sys/types.h>   /* predefined types */
 #include <unistd.h>      /* include unix standard library */
@@ -44,7 +45,6 @@
 #include <errno.h>       /* error code */
 #include <string.h>      /* error strings */
 #include <stdlib.h>
-#define _XOPEN_SOURCE
 #include <sys/poll.h>    /* poll function definition */
 
 #include "macros.h"
@@ -169,7 +169,7 @@ int main(int argc, char *argv[])
     poll_set[max_fd].fd = list_fd;
     /* main loop, wait for connection and data inside a select */
     while (1) {    
-       while ( ((n = poll(poll_set, max_fd, -1)) < 0) 
+       while ( ((n = poll(poll_set, max_fd + 1, -1)) < 0) 
                && (errno == EINTR));         /* wait for data or connection */
        if (n < 0) {                          /* on real error exit */
            PrintErr("poll error");
index c8e9ec4ace77b08e43c309aaffb01e43d0136737..c93dc4ac08b11a16419313a89b1beb90abc53a79 100644 (file)
@@ -688,7 +688,7 @@ conseguente blocco del server su di una \func{write}.
 Le possibili soluzioni in questo caso sono quelle di ritornare ad eseguire il
 ciclo di risposta alle richieste all'interno di processi separati, utilizzare
 un timeout per le operazioni di scrittura, o eseguire queste ultime in
-modalità non bloccante, cocludendo le operazioni qualora non vadano a buon
+modalità non bloccante, concludendo le operazioni qualora non vadano a buon
 fine.
 
 
@@ -700,8 +700,7 @@ Finora abbiamo trattato le problematiche risolubili con l'I/O multiplexing
 impiegando la funzione \func{select}; questo è quello che avviene nella
 maggior parte dei casi, in quanto essa è nata sotto BSD proprio per affrontare
 queste problematiche con i socket.  Abbiamo però visto in
-\secref{sec:file_multiplexing} come esistono altre funzioni che permettono di
-affrontare lo stesso problema e come la funzione \func{poll} possa costituire
+\secref{sec:file_multiplexing} come la funzione \func{poll} possa costituire
 una alternativa a \func{select}, con alcuni vantaggi.\footnote{non soffrendo
   delle limitazioni dovute all'uso dei \textit{file descriptor set}.}
 
@@ -734,11 +733,25 @@ pertanto:
 Come esempio dell'uso di \func{poll} proviamo allora a reimplementare il
 server \textit{echo} secondo lo schema di \figref{fig:TCP_echo_multiplex}
 usando \func{poll} al posto di \func{select}. In questo caso dovremo fare
-qualche modifica, 
-
+qualche modifica, per tenere conto della diversa sintassi delle due funzioni,
+ma la struttura del programma resta sostanzialmente la stessa.
 
 
+\begin{figure}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/poll_echod.c}
+  \end{minipage} 
+  \normalsize
+  \caption{La sezione principale del codice della nuova versione di server
+    \textit{echo} basati sull'uso della funzione \func{poll}.}
+  \label{fig:TCP_PollEchod}
+\end{figure}
 
+In \figref{fig:TCP_PollEchod} è riportata la sezione principale della nuova
+versione del server, la versione completa del codice è riportata nel file
+\file{poll\_echod.c} dei sorgenti allegati alla guida. Al solito si sono
+tralasciate 
 
 
 \section{Le opzioni dei socket}