Una lunga serie di modifiche per tenere conto della riorganizzazione della
[gapil.git] / fileadv.tex
index f343a48fba02af45a22bec250db84cb6ed64b5c8..2d000d8baa659e3a7e35f4bae109e3203262625b 100644 (file)
@@ -32,18 +32,18 @@ ed analizzeremo le varie funzioni usate per implementare questa modalit
 I/O.
 
 
 I/O.
 
 
-\subsection{La problematica dell'\textit{I/O multiplexing} e l'uso
-  dell'\textsl{I/O non-bloccante}}
+\subsection{La problematica dell'\textit{I/O multiplexing}}
 \label{sec:file_noblocking}
 
 Abbiamo visto in \secref{sec:sig_gen_beha}, affrontando la suddivisione fra
 \label{sec:file_noblocking}
 
 Abbiamo visto in \secref{sec:sig_gen_beha}, affrontando la suddivisione fra
-\textit{fast} e \textit{slow} system call, che in certi casi le funzioni di
-I/O possono bloccarsi indefinitamente.\footnote{si ricordi però che questo può
-  accadere solo per le pipe, i socket\index{socket} ed alcuni file di
-  dispositivo\index{file!di dispositivo}; sui file normali le funzioni di
-  lettura e scrittura ritornano sempre subito.}  Ad esempio le operazioni di
-lettura possono bloccarsi quando non ci sono dati disponibili sul descrittore
-su cui si sta operando.
+\textit{fast} e \textit{slow} system call,\index{system call lente} che in
+certi casi le funzioni di I/O possono bloccarsi indefinitamente.\footnote{si
+  ricordi però che questo può accadere solo per le pipe, i
+  socket\index{socket} ed alcuni file di dispositivo\index{file!di
+    dispositivo}; sui file normali le funzioni di lettura e scrittura
+  ritornano sempre subito.}  Ad esempio le operazioni di lettura possono
+bloccarsi quando non ci sono dati 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 si verifica quando si deve operare con
 
 Questo comportamento causa uno dei problemi più comuni che ci si trova ad
 affrontare nelle operazioni di I/O, che si verifica quando si deve operare con
@@ -286,8 +286,8 @@ sotto controllo anche dei file descriptor con \func{select}, in questo caso si
 può fare conto sul fatto che all'arrivo di un segnale essa verrebbe interrotta
 e si potrebbero eseguire di conseguenza le operazioni relative al segnale e
 alla gestione dati con un ciclo del tipo:
 può fare conto sul fatto che all'arrivo di un segnale essa verrebbe interrotta
 e si potrebbero eseguire di conseguenza le operazioni relative al segnale e
 alla gestione dati con un ciclo del tipo:
-\includecodesnip{listati/select_race.c} 
-qui però emerge una race condition, perché se il segnale arriva prima della
+\includecodesnip{listati/select_race.c} qui però emerge una race
+condition,\index{race condition} perché se il segnale arriva prima della
 chiamata a \func{select}, questa non verrà interrotta, e la ricezione del
 segnale non sarà rilevata.
 
 chiamata a \func{select}, questa non verrà interrotta, e la ricezione del
 segnale non sarà rilevata.
 
@@ -407,7 +407,7 @@ compatibilit
   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:
   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
+\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
 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
@@ -433,27 +433,21 @@ tramite \var{errno}.
 
 %da fare
 
 
 %da fare
 
-\section{Altre modalità e funzioni di I/O avanzato}
-\label{sec:file_advanced_io}
+\section{L'accesso \textsl{asincrono} ai file}
+\label{sec:file_asyncronous_access}
 
 Benché l'\textit{I/O multiplexing} sia stata la prima, e sia tutt'ora una fra
 
 Benché l'\textit{I/O multiplexing} sia stata la prima, e sia tutt'ora una fra
-le più diffuse modalità di gestire l'I/O in situazioni complesse che
-coivolgono molti file, esistono altre modalità di gestione delle stesse
-problematiche, oltre che differenti interfacce per la gestione di altre
-problematiche avanzate riguardanti l'I/O su file, tratteremo tutto ciò in
-questa sezione.
-
+le più diffuse modalità di gestire l'I/O in situazioni complesse in cui si
+debba operare su più file contemporaneamente, esistono altre modalità di
+gestione delle stesse problematiche. In particolare sono importanti in questo
+contesto le modalità di accesso ai file eseguibili in maniera
+\textsl{asincrona}, senza cioè che un processo debba bloccarsi, ed utilizzi
+invece un meccanismo di notifica asincrono, come un segnale, per rilevare la
+possibilità di eseguire le operazioni volute.
 
 
-\subsection{L'apertura asincrona dei file}
-\label{sec:file_asyncronous_open}
 
 
-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.
+\subsection{Operazioni asincrone sui file}
+\label{sec:file_asyncronous_operation}
 
 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
 
 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
@@ -463,16 +457,21 @@ attivare in un secondo tempo questa modalit
 l'uso di \func{fcntl} con il comando \const{F\_SETFL} (vedi
 \secref{sec:file_fcntl}). 
 
 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 (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 realtà in questo caso non si tratta di eseguire delle operazioni di lettura
+o scrittura del file in modo asincrono (tratteremo questo, che più
+propriamente è detto \textsl{I/O asincrono} in
+\secref{sec:file_asyncronous_io}), quanto di un meccanismo asincrono di
+notifica delle variazione dello stato del file descriptor aperto in questo
+modo.
+
+Quello che succede è che il sistema genera un segnale (normalmente
+\const{SIGIO}, ma è possibile usarne altri con il comando \const{F\_SETSIG} di
+\func{fcntl}) 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
 
 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
@@ -483,19 +482,22 @@ tenuti sotto controllo per determinare quali di essi (in genere una piccola
 percentuale) sono diventati attivi.
 
 Tuttavia con l'implementazione classica dei segnali questa modalità di I/O
 percentuale) 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 \struct{siginfo\_t}, utilizzando la forma estesa
-\var{sa\_sigaction} del gestore (si riveda quanto illustrato in
+presenta notevoli problemi, dato che non è possibile determinare, quando i
+file descriptor sono più di uno, qual'è quello responsabile dell'emissione del
+segnale; inoltre dato che i segnali normali non si accumulano, in presenza di
+più file descriptor attivi contemporaneamente, più segnali emessi nello stesso
+tempo verrebbero notificati una volta sola. Linux però supporta le estensioni
+POSIX.1b dei segnali real-time, che possono accumularsi e che permettono di
+riconoscere il file descriptor facendo ricorso alle informazioni aggiuntive
+restituite attraverso la struttura \struct{siginfo\_t}, utilizzando la forma
+estesa \var{sa\_sigaction} del gestore (si riveda quanto illustrato in
 \secref{sec:sig_sigaction}).
 
 Per far questo però occorre utilizzare le funzionalità dei segnali real-time
 (vedi \secref{sec:sig_real_time}) impostando esplicitamente con il comando
 \const{F\_SETSIG} di \func{fcntl} un segnale real-time da inviare in caso di
 I/O asincrono (il segnale predefinito è \const{SIGIO}). In questo caso il
 \secref{sec:sig_sigaction}).
 
 Per far questo però occorre utilizzare le funzionalità dei segnali real-time
 (vedi \secref{sec:sig_real_time}) impostando esplicitamente con il comando
 \const{F\_SETSIG} di \func{fcntl} un segnale real-time da inviare in caso di
 I/O asincrono (il segnale predefinito è \const{SIGIO}). In questo caso il
-gestore tutte le volte che riceverà \const{SI\_SIGIO} come valore del
+gestore, tutte le volte che riceverà \const{SI\_SIGIO} come valore del
 campo \var{si\_code}\footnote{il valore resta \const{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
 campo \var{si\_code}\footnote{il valore resta \const{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
@@ -511,20 +513,30 @@ 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 \const{SIGIO}, su cui si accumuleranno tutti i segnali
 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 \const{SIGIO}, su cui si accumuleranno tutti i segnali
-in eccesso, e si dovrà determinare al solito modo quali sono i file diventati
+in eccesso, e si dovrà determinare con un ciclo quali sono i file diventati
 attivi.
 
 attivi.
 
+
 \subsection{L'interfaccia POSIX per l'I/O asincrono}
 \label{sec:file_asyncronous_io}
 
 \subsection{L'interfaccia POSIX per l'I/O asincrono}
 \label{sec:file_asyncronous_io}
 
+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.
+
 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
 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
-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 anche una interfaccia apposita per l'I/O
-asincrono, che prevede un insieme di funzioni dedicate, completamente separate
-rispetto a quelle usate normalmente.
+file per i quali le funzioni di I/O sono \index{system call lente}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 una interfaccia apposita per l'I/O
+asincrono vero e proprio, che prevede un insieme di funzioni dedicate per la
+lettura e la scrittura dei file, completamente separate rispetto a quelle
+usate normalmente.
 
 In generale questa interfaccia è completamente astratta e può essere
 implementata sia direttamente nel kernel, che in user space attraverso l'uso
 
 In generale questa interfaccia è completamente astratta e può essere
 implementata sia direttamente nel kernel, che in user space attraverso l'uso
@@ -864,6 +876,16 @@ la notifica del completamento di tutte le richieste, impostando l'argomento
 di \struct{aiocb}.
 
 
 di \struct{aiocb}.
 
 
+\section{Altre modalità di I/O avanzato}
+\label{sec:file_advanced_io}
+
+Oltre alle precedenti modalità di \textit{I/O multiplexing} e \textsl{I/O
+  asincrono}, esistono altre funzioni che implementano delle modalità di
+accesso ai file più evolute rispetto alle normali funzioni di lettura e
+scrittura che abbiamo esaminato in \secref{sec:file_base_func}. In questa
+sezione allora prenderemo in esame le interfacce per l'\textsl{I/O
+  vettorizzato} e per l'\textsl{I/O mappato in memoria}.
+
 
 \subsection{I/O vettorizzato}
 \label{sec:file_multiple_io}
 
 \subsection{I/O vettorizzato}
 \label{sec:file_multiple_io}
@@ -950,9 +972,9 @@ file in una sezione dello spazio di indirizzi del processo. Il meccanismo 
 illustrato in \figref{fig:file_mmap_layout}, una sezione del file viene
 riportata direttamente nello spazio degli indirizzi del programma. Tutte le
 operazioni su questa zona verranno riportate indietro sul file dal meccanismo
 illustrato in \figref{fig:file_mmap_layout}, una sezione del file viene
 riportata direttamente nello spazio degli indirizzi del programma. Tutte le
 operazioni su questa zona verranno riportate indietro sul file dal meccanismo
-della memoria virtuale che trasferirà il contenuto di quel segmento sul file
-invece che nella swap, per cui si può parlare tanto di file mappato in
-memoria, quanto di memoria mappata su file.
+della memoria virtuale\index{memoria virtuale} che trasferirà il contenuto di
+quel segmento sul file invece che nella swap, per cui si può parlare tanto di
+file mappato in memoria, quanto di memoria mappata su file.
 
 \begin{figure}[htb]
   \centering
 
 \begin{figure}[htb]
   \centering
@@ -971,16 +993,16 @@ memoria solo le parti del file che sono effettivamente usate ad un dato
 istante.
 
 Infatti, dato che l'accesso è fatto direttamente attraverso la memoria
 istante.
 
 Infatti, dato che l'accesso è fatto direttamente attraverso la memoria
-virtuale, la sezione di memoria mappata su cui si opera sarà a sua volta letta
-o scritta sul file una pagina alla volta e solo per le parti effettivamente
-usate, il tutto in maniera completamente trasparente al processo; l'accesso
-alle pagine non ancora caricate avverrà allo stesso modo con cui vengono
-caricate in memoria le pagine che sono state salvate sullo swap.  Infine in
-situazioni in cui la memoria è scarsa, le pagine che mappano un file vengono
-salvate automaticamente, così come le pagine dei programmi vengono scritte
-sulla swap; questo consente di accedere ai file su dimensioni il cui solo
-limite è quello dello spazio di indirizzi disponibile, e non della memoria su
-cui possono esserne lette delle porzioni.
+virtuale,\index{memoria virtuale} la sezione di memoria mappata su cui si
+opera sarà a sua volta letta o scritta sul file una pagina alla volta e solo
+per le parti effettivamente usate, il tutto in maniera completamente
+trasparente al processo; l'accesso alle pagine non ancora caricate avverrà
+allo stesso modo con cui vengono caricate in memoria le pagine che sono state
+salvate sullo swap.  Infine in situazioni in cui la memoria è scarsa, le
+pagine che mappano un file vengono salvate automaticamente, così come le
+pagine dei programmi vengono scritte sulla swap; questo consente di accedere
+ai file su dimensioni il cui solo limite è quello dello spazio di indirizzi
+disponibile, e non della memoria su cui possono esserne lette delle porzioni.
 
 L'interfaccia prevede varie funzioni per la gestione del \textit{memory mapped
   I/O}, la prima di queste è \funcd{mmap}, che serve ad eseguire la mappatura
 
 L'interfaccia prevede varie funzioni per la gestione del \textit{memory mapped
   I/O}, la prima di queste è \funcd{mmap}, che serve ad eseguire la mappatura
@@ -1133,11 +1155,11 @@ come maschera binaria ottenuta dall'OR di uno o pi
 Gli effetti dell'accesso ad una zona di memoria mappata su file possono essere
 piuttosto complessi, essi si possono comprendere solo tenendo presente che
 tutto quanto è comunque basato sul basato sul meccanismo della memoria
 Gli effetti dell'accesso ad una zona di memoria mappata su file possono essere
 piuttosto complessi, essi si possono comprendere solo tenendo presente che
 tutto quanto è comunque basato sul basato sul meccanismo della memoria
-virtuale. Questo comporta allora una serie di conseguenze. La più ovvia è che
-se si cerca di scrivere su una zona mappata in sola lettura si avrà
-l'emissione di un segnale di violazione di accesso (\const{SIGSEGV}), dato che
-i permessi sul segmento di memoria relativo non consentono questo tipo di
-accesso.
+virtuale.\index{memoria virtuale} Questo comporta allora una serie di
+conseguenze. La più ovvia è che se si cerca di scrivere su una zona mappata in
+sola lettura si avrà l'emissione di un segnale di violazione di accesso
+(\const{SIGSEGV}), dato che i permessi sul segmento di memoria relativo non
+consentono questo tipo di accesso.
 
 \begin{figure}[!htb]
   \centering
 
 \begin{figure}[!htb]
   \centering