X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileadv.tex;h=4410d6b126c0193c1703f3d0ab70da7bfe737440;hp=88f6307d5383a74301d8e738a74138b49f6833ae;hb=baec5331e567f35346bf2d0a6938f081d6c698ee;hpb=42a9a2d31d3d0276160e6a0aa385b53c21f6a036 diff --git a/fileadv.tex b/fileadv.tex index 88f6307..4410d6b 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -3493,50 +3493,50 @@ raggruppati in un solo evento. \subsection{L'interfaccia POSIX per l'I/O asincrono} \label{sec:file_asyncronous_io} -% vedere anche http://davmac.org/davpage/linux/async-io.html e -% http://www.ibm.com/developerworks/linux/library/l-async/ - - 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 e gli altri file per i quali -le funzioni di I/O sono \index{system~call~lente} \textit{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. + asincrono} o ``AIO''. 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 vista in +sez.~\ref{sec:signal_driven_io} possa risultare utile in varie occasioni (in +particolar modo con i socket e gli altri file per i quali le funzioni di I/O +sono \index{system~call~lente} \textit{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,\footnote{questa è stata ulteriormente perfezionata nelle successive + versioni POSIX.1-2001 e POSIX.1-2008.} 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 di \itindex{thread} \textit{thread}. Per le versioni del kernel meno recenti -esiste una implementazione di questa interfaccia fornita delle \acr{glibc}, -che è realizzata completamente in user space, ed è accessibile linkando i -programmi con la libreria \file{librt}. Nelle versioni più recenti (a partire -dalla 2.5.32) è stato introdotto direttamente nel kernel un nuovo layer per -l'I/O asincrono. - -Lo standard 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 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. +esiste una implementazione di questa interfaccia fornita completamente delle +\acr{glibc} a partire dalla versione 2.1, che è realizzata completamente in +user space, ed è accessibile linkando i programmi con la libreria +\file{librt}. Nelle versioni più recenti (a partire dalla 2.5.32) è stato +introdotto nel kernel un nuovo layer per l'I/O asincrono, ma ancora il +supporto è parziale ed insufficiente ad implementare l'AIO POSIX. + +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 +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. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{\textwidth} + \begin{minipage}[c]{0.90\textwidth} \includestruct{listati/aiocb.h} - \end{minipage} + \end{minipage} \normalsize \caption{La struttura \structd{aiocb}, usata per il controllo dell'I/O asincrono.} @@ -3578,18 +3578,17 @@ Le due funzioni base dell'interfaccia per l'I/O asincrono sono \funcd{aio\_read} ed \funcd{aio\_write}. Esse permettono di richiedere una lettura od una scrittura asincrona di dati, usando la struttura \struct{aiocb} appena descritta; i rispettivi prototipi sono: -\begin{functions} - \headdecl{aio.h} - \funcdecl{int aio\_read(struct aiocb *aiocbp)} - Richiede una lettura asincrona secondo quanto specificato con \param{aiocbp}. +\begin{funcproto}{ +\fhead{aio.h} +\fdecl{int aio\_read(struct aiocb *aiocbp)} +\fdesc{Richiede una lettura asincrona.} +\fdecl{int aio\_write(struct aiocb *aiocbp)} +\fdesc{Richiede una scrittura asincrona.} +} - \funcdecl{int aio\_write(struct aiocb *aiocbp)} - Richiede una scrittura asincrona secondo quanto specificato con - \param{aiocbp}. - - \bodydesc{Le funzioni restituiscono 0 in caso di successo, e -1 in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori: +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EBADF}] si è specificato un file descriptor sbagliato. \item[\errcode{ENOSYS}] la funzione non è implementata. @@ -3598,7 +3597,8 @@ appena descritta; i rispettivi prototipi sono: \item[\errcode{EAGAIN}] la coda delle richieste è momentaneamente piena. \end{errlist} } -\end{functions} +\end{funcproto} + Entrambe le funzioni ritornano immediatamente dopo aver messo in coda la richiesta, o in caso di errore. Non è detto che gli errori \errcode{EBADF} ed @@ -3620,60 +3620,72 @@ riutilizzare la stessa struttura per un'altra operazione fintanto che la precedente non sia stata ultimata. In generale per ogni operazione si deve utilizzare una diversa struttura \struct{aiocb}. +% vedere anche http://davmac.org/davpage/linux/async-io.html e +% http://www.ibm.com/developerworks/linux/library/l-async/ + Dato che si opera in modalità asincrona, il successo di \func{aio\_read} o \func{aio\_write} non implica che le operazioni siano state effettivamente eseguite in maniera corretta; per verificarne l'esito l'interfaccia prevede altre due funzioni, che permettono di controllare lo stato di esecuzione. La prima è \funcd{aio\_error}, che serve a determinare un eventuale stato di errore; il suo prototipo è: -\begin{prototype}{aio.h} - {int aio\_error(const struct aiocb *aiocbp)} - Determina lo stato di errore delle operazioni di I/O associate a - \param{aiocbp}. - - \bodydesc{La funzione restituisce 0 se le operazioni si sono concluse con - successo, altrimenti restituisce il codice di errore relativo al loro - fallimento.} -\end{prototype} -Se l'operazione non si è ancora completata viene restituito l'errore di -\errcode{EINPROGRESS}. La funzione ritorna zero quando l'operazione si è +\begin{funcproto}{ +\fhead{aio.h} +\fdecl{int aio\_error(const struct aiocb *aiocbp)} +\fdesc{Determina lo stato di errore di una operazione di I/O asincrono.} +} + +{La funzione ritorna $0$ se le operazioni si sono concluse con successo, + altrimenti restituisce \errval{EINPROGRESS} se non sono concluse, + \errcode{ECANCELED} se sono state cancellate o il relativo codice di errore + se sono fallite.} +\end{funcproto} + +Se l'operazione non si è ancora completata viene sempre restituito l'errore di +\errcode{EINPROGRESS}, mentre se è stata cancellata ritorna +\errcode{ECANCELED}. La funzione ritorna zero quando l'operazione si è conclusa con successo, altrimenti restituisce il codice dell'errore verificatosi, ed esegue la corrispondente impostazione di \var{errno}. Il codice può essere sia \errcode{EINVAL} ed \errcode{EBADF}, dovuti ad un valore errato per \param{aiocbp}, che uno degli errori possibili durante l'esecuzione dell'operazione di I/O richiesta, nel qual caso saranno restituiti, a seconda del caso, i codici di errore delle \textit{system call} \func{read}, -\func{write} e \func{fsync}. +\func{write}, \func{fsync} e \func{fdatasync}. Una volta che si sia certi che le operazioni siano state concluse (cioè dopo che una chiamata ad \func{aio\_error} non ha restituito \errcode{EINPROGRESS}), si potrà usare la funzione \funcd{aio\_return}, che permette di verificare il completamento delle operazioni di I/O asincrono; il suo prototipo è: -\begin{prototype}{aio.h} -{ssize\_t aio\_return(const struct aiocb *aiocbp)} -Recupera il valore dello stato di ritorno delle operazioni di I/O associate a -\param{aiocbp}. - -\bodydesc{La funzione restituisce lo stato di uscita dell'operazione - eseguita.} -\end{prototype} +\begin{funcproto}{ +\fhead{aio.h} +\fdecl{ssize\_t aio\_return(const struct aiocb *aiocbp)} +\fdesc{Ottiene lo stato dei risultati di una operazione di I/O asincrono.} +} + +{La funzione ritorna lo stato di uscita dell'operazione eseguita (il valore + che avrebbero restituito le equivalenti funzioni eseguite in maniera + sincrona).} +\end{funcproto} -La funzione deve essere chiamata una sola volte per ciascuna operazione -asincrona, essa infatti fa sì che il sistema rilasci le risorse ad essa -associate. É per questo motivo che occorre chiamare la funzione solo dopo che -l'operazione cui \param{aiocbp} fa riferimento si è completata. Una chiamata -precedente il completamento delle operazioni darebbe risultati indeterminati. +La funzione recupera il valore dello stato di ritorno delle operazioni di I/O +associate a \param{aiocbp} deve essere chiamata una sola volta per ciascuna +operazione asincrona, essa infatti fa sì che il sistema rilasci le risorse ad +essa associate. É per questo motivo che occorre chiamare la funzione solo dopo +che l'operazione cui \param{aiocbp} fa riferimento si è completata +verificandolo con \func{aio\_error} ed una sola volta. Una chiamata precedente +il completamento delle operazioni darebbe risultati indeterminati, così come +chiamarla più di una volta. La funzione restituisce il valore di ritorno relativo all'operazione eseguita, così come ricavato dalla sottostante \textit{system call} (il numero di byte -letti, scritti o il valore di ritorno di \func{fsync}). É importante chiamare -sempre questa funzione, altrimenti le risorse disponibili per le operazioni di -I/O asincrono non verrebbero liberate, rischiando di arrivare ad un loro -esaurimento. +letti, scritti o il valore di ritorno di \func{fsync} o \func{fdatasync}). É +importante chiamare sempre questa funzione, altrimenti le risorse disponibili +per le operazioni di I/O asincrono non verrebbero liberate, rischiando di +arrivare ad un loro esaurimento. Oltre alle operazioni di lettura e scrittura l'interfaccia POSIX.1b mette a disposizione un'altra operazione, quella di sincronizzazione dell'I/O, @@ -3828,6 +3840,12 @@ il chiamante può richiedere la notifica del completamento di tutte le richieste, impostando l'argomento \param{sig} in maniera analoga a come si fa per il campo \var{aio\_sigevent} di \struct{aiocb}. +% TODO: trattare libaio e le system call del kernel per l'I/O asincrono, vedi +% http://lse.sourceforge.net/io/aio.html, +% http://webfiveoh.com/content/guides/2012/aug/mon-13th/linux-asynchronous-io-and-libaio.html, +% https://code.google.com/p/kernel/wiki/AIOUserGuide, +% http://bert-hubert.blogspot.de/2012/05/on-linux-asynchronous-file-io.html + \section{Altre modalità di I/O avanzato} \label{sec:file_advanced_io}