Iniziato a rivedere il multiplexing I/O.
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 24 Aug 2003 22:50:27 +0000 (22:50 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 24 Aug 2003 22:50:27 +0000 (22:50 +0000)
fileadv.tex
gapil.tex
system.tex
tcpsock.tex
tcpsockadv.tex [new file with mode: 0644]

index 9c09c7e..4415602 100644 (file)
@@ -70,15 +70,15 @@ I/O non bloccante.
 \label{sec:file_multiplexing}
 
 Per superare il problema di dover usare il \textit{polling}\index{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}\index{socket}, compreso le varianti di System V.}  con la
-funzione \funcd{select}, il cui prototipo è:
+controllare la possibilità di effettuare operazioni su un gruppo di file
+aperti in modalità non bloccante, sia BSD che System V hanno introdotto delle
+nuove funzioni in grado di sospendere l'esecuzione di un processo fin quando
+l'accesso ad un dato insieme di file 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}\index{socket}, compreso le varianti di System
+  V.}  con la funzione \funcd{select}, il cui prototipo è:
 \begin{functions}
   \headdecl{sys/time.h}
   \headdecl{sys/types.h}
@@ -135,10 +135,14 @@ opportune macro di preprocessore:
 In genere un \textit{file descriptor set} può contenere fino ad un massimo di
 \const{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
+  fino alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma da
 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}.
+  descriptor set}.\footnote{il suo valore, secondo lo standard POSIX
+  1003.1-2001, è definito in \file{sys/select.h}, ed è pari a 1024.} Si tenga
+presente che i \textit{file descriptor set} devono sempre essere inizializzati
+con \macro{FD\_ZERO}; passare a \func{select} un valore non inizializzato può
+dar luogo a comportamenti non prevedibili.
 
 La funzione richiede di specificare tre insiemi distinti di file descriptor;
 il primo, \param{readfds}, verrà osservato per rilevare la disponibilità di
@@ -147,17 +151,24 @@ possibilit
 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 \const{FD\_SETSIZE}, oppure il numero
-più alto dei file descriptor usati nei tre insiemi, aumentato di uno.
+Dato che in genere non si tengono mai sotto controllo fino a
+\const{FD\_SETSIZE} file contemporaneamente la funzione richiede di
+specificare qual'è il numero massimo dei file descriptor indicati nei tre
+insiemi precedenti. Questo viene fatto per efficienza, per evitare di passare
+e far controllare al kernel una quantità di memoria superiore a quella
+necessaria. Questo limite viene indicato tramite l'argomento \param{n}, che
+deve corrispondere al valore massimo aumentato di uno.\footnote{i file
+  descriptor infatti sono contati a partire da zero, ed il valore indica il
+  numero di quelli da tenere sotto controllo; dimenticarsi di aumentare di uno
+  il valore di \param{n} è un errore comune.}
 
 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 impostato a \val{NULL} la funzione attende
-indefinitamente. Si può specificare anche un tempo nullo (cioè una struttura
-\struct{timeval} con i campi impostati a zero), qualora si voglia
-semplicemente controllare lo stato corrente dei file descriptor.
+attesa\footnote{il tempo è valutato come \textit{clock time} (vedi
+  \secref{sec:sys_unix_time}).} prima che la funzione ritorni; se impostato a
+\val{NULL} la funzione attende indefinitamente. Si può specificare anche un
+tempo nullo (cioè una struttura \struct{timeval} con i campi impostati 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
@@ -167,35 +178,35 @@ operazioni ad esso relative, in modo da poterlo controllare con la macro
 non vengono toccati.
 
 In Linux \func{select} modifica anche il valore di \param{timeout},
-impostandolo al tempo restante; questo è utile quando la funzione viene
-interrotta da un segnale, in tal caso infatti si ha un errore di
-\errcode{EINTR}, ed occorre rilanciare la funzione; in questo modo non è
-necessario ricalcolare tutte le volte il tempo rimanente.\footnote{questo 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 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 e dalle \acr{libc} 5.4.28.} il cui
+impostandolo al tempo restante in caso di interruzione prematura; questo è
+utile quando la funzione viene interrotta da un segnale, in tal caso infatti
+si ha un errore di \errcode{EINTR}, ed occorre rilanciare la funzione; in
+questo modo non è necessario ricalcolare tutte le volte il tempo
+rimanente.\footnote{questo 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 creata nello
+sviluppo di BSD; anche System V 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 e dalle \acr{libc} 5.4.28.} 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}.
+  
+  La funzione attende 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} assumerà uno dei valori:
   \begin{errlist}
   \item[\errcode{EBADF}] Si è specificato un file descriptor sbagliato in uno
-  degli insiemi.
+    degli insiemi.
   \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
   \end{errlist}
   ed inoltre \errval{EFAULT} e \errval{ENOMEM}.}
@@ -248,7 +259,8 @@ vengono utilizzati solo per \var{revents} come valori in uscita).
     \const{POLLWRNORM}& 0x100 & È possibile la scrittura di dati normali.  \\ 
     \const{POLLWRBAND}& 0x200 & È possibile la scrittura di dati ad 
                                 alta priorità. \\
-    \const{POLLMSG}   & 0x400 & Estensione propria di Linux.\\
+    \const{POLLMSG}   & 0x400 & Un segnale \const{SIGPOLL} è arrivato alla
+                                cima dello stream.\\
     \hline    
   \end{tabular}
   \caption{Costanti per l'identificazione dei vari bit dei campi
@@ -315,6 +327,15 @@ segnale che non sarebbe rilevato; la race condition\index{race condition}
 diventa superabile disabilitando il segnale prima del test e riabilitandolo
 poi grazie all'uso di \param{sigmask}.
 
+Dato che l'I/O multiplexing serve a risolvere il problema di dover attendere
+la disponibilità di accesso ad un insieme di file, esso viene utilizzato
+prevalentemente per programmi in cui l'accesso ad un file descriptor può
+essere bloccante. Abbiamo già accennato come questo non avvenga mai per i
+normali file su disco; l'uso più comune di queste funzioni infatti è nei
+server di rete, in cui esse vengono utilizzate per tenere sotto controllo vari
+socket; pertanto ritorneremo su di esse con maggiori dettagli e con qualche
+esempio in \secref{sec:TCP_sock_multiplexing}.
+
 
 
 \subsection{L'I/O asincrono}
index 1d18318..62f70cb 100644 (file)
--- a/gapil.tex
+++ b/gapil.tex
 \include{network}
 \include{socket}
 \include{tcpsock}
-%\include{simpltcp}
+\include{tcpsockadv}
 \appendix
 \include{netlayer}
 \include{trasplayer}
index 2427fee..60ca1e9 100644 (file)
@@ -1643,9 +1643,9 @@ dei tempi di esecuzione dei processi. Per ciascun processo il kernel calcola
 tre tempi diversi:
 \begin{description}
 \item[\textit{clock time}]: il tempo \textsl{reale} (viene chiamato anche
-  \textit{wall clock time}) passato dall'avvio del processo. Chiaramente tale
-  tempo dipende anche dal carico del sistema e da quanti altri processi
-  stavano girando nello stesso periodo.
+  \textit{wall clock time} o \textit{elapsed time}) passato dall'avvio del
+  processo. Chiaramente tale tempo dipende anche dal carico del sistema e da
+  quanti altri processi stavano girando nello stesso periodo.
 \item[\textit{user time}]: il tempo che la CPU ha impiegato nell'esecuzione
   delle istruzioni del processo in user space.
 \item[\textit{system time}]: il tempo che la CPU ha impiegato nel kernel per
index 6d23c10..eba896e 100644 (file)
@@ -2384,7 +2384,7 @@ definitiva della connessione anche nel client, dove non comparir
 nell'output di \cmd{netstat}.
 
 Come abbiamo accennato in \secref{sec:TCP_conn_term} e come vedremo più avanti
-in \secref{sec:TCP_xxx_shutdown}} la chiusura di un solo capo di un socket è
+in \secref{sec:TCP_xxx_shutdown} la chiusura di un solo capo di un socket è
 una operazione lecita, per cui la nostra scrittura avrà comunque successo
 (come si può constatare lanciando usando \cmd{strace}\footnote{il comando
   \cmd{strace} è un comando di debug molto utile che prende come parametro un
diff --git a/tcpsockadv.tex b/tcpsockadv.tex
new file mode 100644 (file)
index 0000000..3ac5348
--- /dev/null
@@ -0,0 +1,72 @@
+%% tcpsockadv.tex
+%%
+%% Copyright (C) 2003 Simone Piccardi.  Permission is granted to
+%% copy, distribute and/or modify this document under the terms of the GNU Free
+%% Documentation License, Version 1.1 or any later version published by the
+%% Free Software Foundation; with the Invariant Sections being "Prefazione",
+%% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
+%% license is included in the section entitled "GNU Free Documentation
+%% License".
+%%
+\chapter{Socket TCP avanzati}
+\label{cha:TCP_advanced}
+
+Esamineremo in questo capitolo le funzionalità più evolute della gestione dei
+socket TCP. 
+
+
+
+\section{Socket multiplexing}
+\label{sec:TCP_sock_mutiplexing}
+
+Affronteremo in questa sezione l'utilizzo dei socket 
+
+
+
+\section{Le opzioni dei socket}
+\label{sec:TCP_sock_options}
+
+Dato che la maggior parte delle opzioni dei socket sono relative ai socket
+TCP, ed hanno poi significato analogo quando usate con altri socket,
+tratteremo qui l'argomento in generale.
+
+
+
+\section{I dati \textit{out-of-band}}
+\label{sec:TCP_outofband}
+
+Una caratteristica speciale dei socket TCP è quella della presenza dei
+cosiddetti dati \textit{out-of-band}
+
+
+
+\subsection{La funzione \func{shutdown}}
+\label{sec:TCP_shutdown}
+
+Come spiegato in \secref{sec:TCP_conn_term} il procedimento di chiusura di un
+socket TCP prevede che da entrambe le parti venga emesso un segmento FIN. È
+pertanto del tutto normale dal punto di vista del protocollo che uno dei due
+capi chiuda la connessione, quando l'altro capo la lascia
+aperta.\footnote{abbiamo incontrato questa situazione nei vari scenari critici
+  di \secref{sec:TCP_echo_critical}.}
+
+È pertanto possibile avere una situazione in cui un capo della connessione non
+avendo più nulla da scrivere, possa chiudere il socket, segnalando così
+l'avvenuta terminazione della trasmissione (l'altro capo riceverà infatti un
+end-of-file in lettura) mentre dall'altra parte si potrà proseguire la
+trasmissione dei dati scrivendo sul socket che da quel lato è ancora aperto.
+Questa è quella situazione in cui si dice che il socket è \textit{half
+  closed}.
+
+Il problema che si pone è che se la chiusura del socket è effettuata con la
+funzione \func{close}, come spiegato in \secref{sec:TCP_func_close}, si perde
+ogni possibilità di poter rileggere quanto l'altro capo può continuare a
+scrivere. Per poter permettere allora 
+
+
+
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: