X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileadv.tex;h=5b0816293e0a5379d8cd3b8c6bb67458887cc3b1;hp=d744a758905558b00fe24189ce811a6b41c9a064;hb=bf78d63598adf72d71aeea3c32277dd63484bb02;hpb=38dff25efc0d3ae24d82724cd196c583c2362737 diff --git a/fileadv.tex b/fileadv.tex index d744a75..5b08162 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -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 @@ -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,39 @@ 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. +\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 normalmente quando vengono usate con un grande numero di file descriptor, +non hanno buone prestazioni, in quanto passano maggior parte del tempo ad +eseguire uno scan per determinare quali sono quelli (in genere un piccola +percentuale) che sono diventati attivi. 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. +dovrebbe provvedere ad effettuare un controllo, utilizzando di nuovo +\func{poll} o \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 -\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 +\secref{sec:sig_sigaction}). + +Per attivare questa caratteristica 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 (di norma viene usato \macro{SIGIO}). 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 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. +\func{poll} o \func{select}. Benché la modalità di apertura asincrona di un file possa risultare utile in varie occasioni (in particolar modo con i socket e gli altri file per i quali @@ -396,8 +400,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.