Ulteriori correzioni all'appendice su IPv6.
[gapil.git] / fileadv.tex
index 591f1494453baa0b6ea51d51d13f5c518dd8d0bf..2f16a2759b42799018f3275428c967a6cee3ae0e 100644 (file)
@@ -31,12 +31,11 @@ disponibili sul descrittore su cui si sta operando.
 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.
+mentre si è bloccati su uno di essi 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
+Abbiamo già accennato in \secref{sec:file_open} che è possibile prevenire
 questo tipo di comportamento aprendo un file in modalità
 \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
@@ -158,12 +157,12 @@ 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.}
+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
@@ -325,7 +324,7 @@ del flag \macro{O\_ASYNC},\footnote{l'uso del flag di \macro{O\_ASYNC} e dei
   di Linux e BSD.} aprire un file in modalità asincrona, così come è possibile
 attivare in un secondo tempo questa modalità settando questo flag attraverso
 l'uso di \func{fcntl} con il comando \macro{F\_SETFL} (vedi
-\secref{sec:file_fcntl}).
+\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
@@ -333,34 +332,47 @@ descriptor; quello che succede 
 \macro{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 \macro{F\_SETOWN} di
-\func{fcntl}, quale processo (o gruppo di processi) riceverà il segnale.
-
-Uno dei problemi che si presenta con l'implementazione usuale di questa
-modalità di I/O è che essa può essere usata in maniera immediata aprendo in
-modalità asincrona un solo file per processo, altrimenti ad ogni segnale si
-dovrebbe provvedere ad effettuare un controllo (utilizzando di nuovo
-\func{select}) su tutti i file tenuti in modalità asincrona per distinguere
-quelli cui è dovuta l'emissione del segnale.
-
-Linux però supporta una estensione che permette di evitare tutto questo
-facendo ricorso alle informazioni aggiuntive restituite attraverso la
-struttura \type{siginfo\_t} quando il manipolatore del segnale viene
-installato come \macro{SA\_SIGINFO} (si riveda quanto illustrato in
+\func{fcntl}, quale processo (o gruppo di processi) riceverà il segnale. 
+
+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
+di esecuzione è impegato per eseguire uno scan su tutti i file descriptor
+tenuti sotto controllo per determinare quali sono quelli (in genere un piccola
+percentuale) che sono diventati attivi.
+
+Tuttavia con l'implementazione classica dei segnali questa modalità di I/O
+presenta notevoli problemi, dato che non è possibile determinare, quando sono
+più di uno, qual'è il file descriptor responsabile dell'emissione del segnale.
+Linux però supporta le estensioni POSIX.1b dei segnali che permettono di
+superare il problema facendo ricorso alle informazioni aggiuntive restituite
+attraverso la struttura \type{siginfo\_t}, utilizzando la forma estesa
+\var{sa\_sigaction} del manipolatore (si riveda quanto illustrato in
 \secref{sec:sig_sigaction}).
 
-Per attivare questa caratteristica occorre settare esplicitamente il segnale
-da inviare in caso di I/O asincrono (di norma sempre \macro{SIGIO}) con il
-comando \macro{F\_SETSIG} di \func{fcntl}. In questo caso il manipolatore
-tutte le volte che riceverà \macro{SI\_SIGIO} come valore del campo
-\var{si\_code}\footnote{il valore resta \macro{SI\_SIGIO} qualunque sia il
-  segnale che si è associato all'I/O asincrono, ed indica appunto che il
+Per far questo però occorre utilizzare le funzionalità dei segnali real-time
+(vedi \secref{sec:sig_real_time}) settando esplicitamente con il comando
+\macro{F\_SETSIG} di \func{fcntl} un segnale real-time da inviare in caso di
+I/O asincrono (il segnale di default è \macro{SIGIO}). In questo caso il
+manipolatorem tutte le volte che riceverà \macro{SI\_SIGIO} come valore del
+campo \var{si\_code}\footnote{il valore resta \macro{SI\_SIGIO} qualunque sia
+  il segnale che si è associato all'I/O asincrono, ed indica appunto che il
   segnale è stato generato a causa di attività nell'I/O asincrono.} di
 \type{siginfo\_t}, troverà nel campo \var{si\_fd} il valore del file
-descriptor che ha generato il segnale. In questo modo è possibile identificare
-immediatamente il file evitando completamente l'uso di funzioni come
-\func{poll} o \func{select}. Inoltre, a differenza degli altri segnali, il
-sistema mantiene una coda per \macro{SIGIO}, in modo che arrivi un segnale per
-ogni file attivo.
+descriptor che ha generato il segnale.
+
+Un secondo vantaggio dell'uso dei segnali real-time è che essendo dotati di
+una coda di consegna ogni segnale sarà associato ad uno solo file descriptor;
+inoltre sarà possibile stabilire delle priorità nella risposta a seconda del
+segnale usato. In questo modo si può identificare immediatamente un file su
+cui l'accesso è diventato possibile evitando completamente l'uso di funzioni
+come \func{poll} e \func{select}, almeno fintanto che non si satura la coda;
+si eccedono le dimensioni di quest'ultima; in tal caso infatti il kernel, non
+potendo più assicurare il comportamento corretto per un segnale real-time,
+invierà al suo posto un \var{SIGIO}, su cui si accumuleranno tutti i segnali
+in eccesso, e si dovra determinare al solito modo quali sono i file diventati
+attivi.
+
 
 
 Benché la modalità di apertura asincrona di un file possa risultare utile in
@@ -368,25 +380,20 @@ varie occasioni (in particolar modo con i socket e gli altri file per i quali
 le funzioni di I/O sono system call lente), essa è comunque limitata alla
 notifica della disponibilità del file descriptor per le operazioni di I/O, e
 non ad uno svolgimento asincrono delle medesime.  Lo standard POSIX.1b
-definisce invece una interfaccia apposita per l'I/O asincrono, che prevede un
-insieme di funzioni dedicate, completamente separato rispetto a quelle usate
+definisce anche una interfaccia apposita per l'I/O asincrono, che prevede un
+insieme di funzioni dedicate, completamente separate rispetto a quelle usate
 normalmente.
 
 In generale questa interfaccia è completamente astratta e può essere
-implementata sia direttamente nel kernel, che attraverso l'uso di thread. Al
-momento\footnote{fino ai kernel della serie 2.4.x sono presenti solo le due
-  alternative citate, nella serie 2.5.x è però iniziato un lavoro completo di
-  riscrittura di tutto il sistema di I/O, che prevede anche l'introduzione di
-  un nuovo layer per l'I/O asincrono.} sono disponibili due implementazioni,
-una in user space, che è integrata nelle \acr{glibc}, ed una ibrida, che si
-appoggia ad una estensione del kernel (il cosiddetto KAIO, non incluso nella
-versione ufficiale) prodotta da SGI. Quest'ultima ha funzionalità più limitate
-ma prestazioni nettamente superiori.
-
-Alle funzioni definite essa si può accedere includendo \file{unistd.h} e
-definendo la macro \macro{\_POSIX\_ASYNCHRONOUS\_IO}, mentre alla
-implementazione di KAIO si accede includendo \file{linux/aio.h}; ambedue però
-usano la stessa interfaccia di programmazione.
+implementata sia direttamente nel kernel, che in user space attraverso l'uso
+di thread. Al momento\footnote{fino ai kernel della serie 2.4.x, nella serie
+  2.5.x è però iniziato un lavoro completo di riscrittura di tutto il sistema
+  di I/O, che prevede anche l'introduzione di un nuovo layer per l'I/O
+  asincrono.} esiste una sola versione stabile di questa interfaccia, quella
+delle \acr{glibc}, che è realizzata completamente in user space.  Esistono
+comunque vari progetti sperimentali (come il KAIO della SGI, o i patch di
+Benjamin La Haise) che prevedono una interfaccia che utilizza un supporto
+diretto da parte del kernel.
 
 
 
@@ -403,8 +410,14 @@ vari buffer. In questo caso
 \subsection{File mappati in memoria}
 \label{sec:file_memory_map}
 
-
-
+Una modalità alternativa di I/O, che usa una interfaccia completamente diversa
+rispetto a quella classica, è quella dei file \textsl{mappati in memoria}. In
+sostanza quello che si fa è usare il meccanismo della
+\textsl{paginazione}\index{paginazione} usato per la memoria virtuale (vedi
+\secref{sec:proc_mem_gen}) per trasformare vedere il file in una sezione dello
+spazio di indirizzi del processo, in modo che l'accesso a quest'ultimo con le
+normali operazioni di lettura e scrittura delle variabili in memoria, si
+trasformi in I/O sul file stesso.