X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileadv.tex;h=2e9e781523d5c1ba4b0c1ee6ff4af92b723902f7;hp=9c06b50d8b0edab32edd4dd4d5c61fd50cf7ad04;hb=5afbcf1d6a84ab2a527859d8fd05b75a31e39736;hpb=7208522fd60468969d96dba5d8dd2cbd24b75b89 diff --git a/fileadv.tex b/fileadv.tex index 9c06b50..2e9e781 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -237,7 +237,7 @@ diversi che aprono lo stesso file. In particolare, come accennato in fig.~\ref{fig:file_flock_struct}, i \textit{file lock} sono mantenuti in una \textit{linked list} di strutture -\kstruct{file\_lock}. La lista è referenziata dall'indirizzo di partenza +\kstructd{file\_lock}. La lista è referenziata dall'indirizzo di partenza mantenuto dal campo \var{i\_flock} della struttura \kstruct{inode} (per le definizioni esatte si faccia riferimento al file \file{include/linux/fs.h} nei sorgenti del kernel). Un bit del campo \var{fl\_flags} di specifica se si @@ -481,7 +481,7 @@ sez.~\ref{sec:file_flock}) esaminiamo più in dettaglio come viene gestito dal kernel. Lo schema delle strutture utilizzate è riportato in fig.~\ref{fig:file_posix_lock}; come si vede esso è molto simile all'analogo di fig.~\ref{fig:file_flock_struct}. In questo caso nella figura si sono -evidenziati solo i campi di \kstruct{file\_lock} significativi per la +evidenziati solo i campi di \kstructd{file\_lock} significativi per la semantica POSIX, in particolare adesso ciascuna struttura contiene, oltre al \ids{PID} del processo in \var{fl\_pid}, la sezione di file che viene bloccata grazie ai campi \var{fl\_start} e \var{fl\_end}. La struttura è comunque la @@ -1041,7 +1041,7 @@ degli insiemi specificati (\param{readfds}, \param{writefds} e Per specificare quali file descriptor si intende selezionare la funzione usa un particolare oggetto, il \textit{file descriptor set}, identificato dal tipo -\type{fd\_set}, che serve ad identificare un insieme di file descriptor, in +\typed{fd\_set}, che serve ad identificare un insieme di file descriptor, in maniera analoga a come un \textit{signal set} (vedi sez.~\ref{sec:sig_sigset}) identifica un insieme di segnali. Per la manipolazione di questi \textit{file descriptor set} si possono usare delle opportune macro di preprocessore: @@ -1134,7 +1134,6 @@ riaperto. Lo standard non prevede niente al riguardo e non si deve dare per assunto nessuno dei due comportamenti se si vogliono scrivere programmi portabili. - \itindend{file~descriptor~set} Una volta ritornata la funzione, si potrà controllare quali sono i file @@ -1182,7 +1181,7 @@ Lo standard POSIX è rimasto a lungo senza primitive per l'\textit{I/O multiplexing}, introdotto solo con le ultime revisioni dello standard (POSIX 1003.1g-2000 e POSIX 1003.1-2001). La scelta è stata quella di seguire l'interfaccia creata da BSD, ma prevede che tutte le funzioni ad esso relative -vengano dichiarate nell'header \headfile{sys/select.h}, che sostituisce i +vengano dichiarate nell'header \headfiled{sys/select.h}, che sostituisce i precedenti, ed inoltre aggiunge a \func{select} una nuova funzione \funcd{pselect},\footnote{il supporto per lo standard POSIX 1003.1-2001, ed l'header \headfile{sys/select.h}, compaiono in Linux a partire dalle @@ -1285,7 +1284,7 @@ interfaccia completamente diversa, basata sulla funzione di sistema introdotta in Linux come \textit{system call} a partire dal kernel 2.1.23 ed inserita nelle \acr{libc} 5.4.28, originariamente l'argomento \param{nfds} era di tipo \ctyp{unsigned int}, la funzione è stata inserita nello standard - POSIX.1-2001 in cui è stato introdotto il tipo nativo \type{nfds\_t}.} il + POSIX.1-2001 in cui è stato introdotto il tipo nativo \typed{nfds\_t}.} il cui prototipo è: \begin{funcproto}{ @@ -1425,20 +1424,19 @@ solito tramite \var{errno}. L'uso di \func{poll} consente di superare alcuni dei problemi illustrati in precedenza per \func{select}; anzitutto, dato che in questo caso si usa un vettore di strutture \struct{pollfd} di dimensione arbitraria, non esiste il -limite introdotto dalle dimensioni massime di un \itindex{file~descriptor~set} -\textit{file descriptor set} e la dimensione dei dati passati al kernel -dipende solo dal numero dei file descriptor che si vogliono controllare, non -dal loro valore. Infatti, anche se usando dei bit un \textit{file descriptor - set} può essere più efficiente di un vettore di strutture \struct{pollfd}, -qualora si debba osservare un solo file descriptor con un valore molto alto ci -si troverà ad utilizzare inutilmente un maggiore quantitativo di memoria. - -Inoltre con \func{select} lo stesso \itindex{file~descriptor~set} \textit{file - descriptor set} è usato sia in ingresso che in uscita, e questo significa -che tutte le volte che si vuole ripetere l'operazione occorre reinizializzarlo -da capo. Questa operazione, che può essere molto onerosa se i file descriptor -da tenere sotto osservazione sono molti, non è invece necessaria con -\func{poll}. +limite introdotto dalle dimensioni massime di un \textit{file descriptor set} +e la dimensione dei dati passati al kernel dipende solo dal numero dei file +descriptor che si vogliono controllare, non dal loro valore. Infatti, anche se +usando dei bit un \textit{file descriptor set} può essere più efficiente di un +vettore di strutture \struct{pollfd}, qualora si debba osservare un solo file +descriptor con un valore molto alto ci si troverà ad utilizzare inutilmente un +maggiore quantitativo di memoria. + +Inoltre con \func{select} lo stesso \textit{file descriptor set} è usato sia +in ingresso che in uscita, e questo significa che tutte le volte che si vuole +ripetere l'operazione occorre reinizializzarlo da capo. Questa operazione, che +può essere molto onerosa se i file descriptor da tenere sotto osservazione +sono molti, non è invece necessaria con \func{poll}. Abbiamo visto in sez.~\ref{sec:file_select} come lo standard POSIX preveda una variante di \func{select} che consente di gestire correttamente la ricezione @@ -1507,11 +1505,11 @@ Nonostante \func{poll} presenti alcuni vantaggi rispetto a \func{select}, anche questa funzione non è molto efficiente quando deve essere utilizzata con un gran numero di file descriptor,\footnote{in casi del genere \func{select} viene scartata a priori, perché può avvenire che il numero di file - descriptor ecceda le dimensioni massime di un \itindex{file~descriptor~set} - \textit{file descriptor set}.} in particolare nel caso in cui solo pochi di -questi diventano attivi. Il problema in questo caso è che il tempo impiegato -da \func{poll} a trasferire i dati da e verso il kernel è proporzionale al -numero di file descriptor osservati, non a quelli che presentano attività. + descriptor ecceda le dimensioni massime di un \textit{file descriptor set}.} +in particolare nel caso in cui solo pochi di questi diventano attivi. Il +problema in questo caso è che il tempo impiegato da \func{poll} a trasferire i +dati da e verso il kernel è proporzionale al numero di file descriptor +osservati, non a quelli che presentano attività. Quando ci sono decine di migliaia di file descriptor osservati e migliaia di eventi al secondo (il caso classico è quello di un server web di un sito con @@ -1836,7 +1834,7 @@ modificano le modalità di notifica. ed è utile per riconoscere la chiusura di una connessione dall'altro capo di un socket quando si lavora in modalità \textit{edge triggered}.} -Il secondo campo, \var{data}, è una \direct{union} che serve a identificare il +Il secondo campo, \var{data}, è una \dirct{union} che serve a identificare il file descriptor a cui si intende fare riferimento, ed in astratto può contenere un valore qualsiasi (specificabile in diverse forme) che ne permetta una indicazione univoca. Il modo più comune di usarlo però è quello in cui si @@ -2594,7 +2592,7 @@ funzioni dell'I/O multiplexing viste in precedenza. Una volta che il file descriptor risulta pronto sarà possibile leggere il numero di volte che il timer è scaduto con una ordinaria \func{read}. -La funzione legge il valore in un dato di tipo \type{uint64\_t}, e necessita +La funzione legge il valore in un dato di tipo \typed{uint64\_t}, e necessita pertanto che le si passi un buffer di almeno 8 byte, fallendo con \errval{EINVAL} in caso contrario, in sostanza la lettura deve essere effettuata con una istruzione del tipo: @@ -2720,7 +2718,7 @@ avvenga è di impostare la lunghezza della coda dei segnali \textit{real-time} ad una dimensione identica al valore massimo del numero di file descriptor utilizzabili, vale a dire impostare il contenuto di \sysctlfile{kernel/rtsig-max} allo stesso valore del contenuto di -\sysctlfile{fs/file-max}. +\sysctlfilem{fs/file-max}. % TODO fare esempio che usa O_ASYNC @@ -3034,10 +3032,9 @@ stato smontato. Inoltre trattandosi di un file descriptor a tutti gli effetti, esso potrà essere utilizzato come argomento per le funzioni \func{select} e \func{poll} e con l'interfaccia di \textit{epoll}, ed a partire dal kernel 2.6.25 è stato -introdotto anche il supporto per il \itindex{signal~driven~I/O} -\texttt{signal-driven I/O}. Siccome gli eventi vengono notificati come dati -disponibili in lettura, dette funzioni ritorneranno tutte le volte che si avrà -un evento di notifica. +introdotto anche il supporto per il \texttt{signal-driven I/O}. Siccome gli +eventi vengono notificati come dati disponibili in lettura, dette funzioni +ritorneranno tutte le volte che si avrà un evento di notifica. Così, invece di dover utilizzare i segnali, considerati una pessima scelta dal punto di vista dell'interfaccia utente, si potrà gestire l'osservazione degli @@ -3336,15 +3333,15 @@ così all'applicazione di collegare la corrispondente coppia di eventi Infine due campi \var{name} e \var{len} sono utilizzati soltanto quando l'evento è relativo ad un file presente in una directory posta sotto osservazione, in tal caso essi contengono rispettivamente il nome del file -(come \itindsub{pathname}{relativo} \textit{pathname} relativo alla directory -osservata) e la relativa dimensione in byte. Il campo \var{name} viene sempre -restituito come stringa terminata da NUL, con uno o più zeri di terminazione, -a seconda di eventuali necessità di allineamento del risultato, ed il valore -di \var{len} corrisponde al totale della dimensione di \var{name}, zeri -aggiuntivi compresi. La stringa con il nome del file viene restituita nella -lettura subito dopo la struttura \struct{inotify\_event}; questo significa che -le dimensioni di ciascun evento di \textit{inotify} saranno pari a -\code{sizeof(\struct{inotify\_event}) + len}. +(come \textit{pathname} relativo alla directory osservata) e la relativa +dimensione in byte. Il campo \var{name} viene sempre restituito come stringa +terminata da NUL, con uno o più zeri di terminazione, a seconda di eventuali +necessità di allineamento del risultato, ed il valore di \var{len} corrisponde +al totale della dimensione di \var{name}, zeri aggiuntivi compresi. La stringa +con il nome del file viene restituita nella lettura subito dopo la struttura +\struct{inotify\_event}; questo significa che le dimensioni di ciascun evento +di \textit{inotify} saranno pari a \code{sizeof(\struct{inotify\_event}) + + len}. Vediamo allora un esempio dell'uso dell'interfaccia di \textit{inotify} con un semplice programma che permette di mettere sotto osservazione uno o più file e @@ -3517,7 +3514,7 @@ Lo standard POSIX prevede che tutte le operazioni di I/O asincrono siano controllate attraverso l'uso di una apposita struttura \struct{aiocb} (il cui nome sta per \textit{asyncronous I/O control block}), che viene passata come argomento a tutte le funzioni dell'interfaccia. La sua definizione, come -effettuata in \headfile{aio.h}, è riportata in +effettuata in \headfiled{aio.h}, è riportata in fig.~\ref{fig:file_aiocb}. Nello steso file è definita la macro \macro{\_POSIX\_ASYNCHRONOUS\_IO}, che dichiara la disponibilità dell'interfaccia per l'I/O asincrono.