X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=fileadv.tex;h=a7851b65ab0347b71be5be874181dce85a6225a7;hb=45633dbe15fd23b17a975eb4d9c231d22a67ac00;hp=5fa13de21efd25ed84475cd07b761ef62077f965;hpb=39c051cd723e36a31bd8989c01970cf712f0d2dd;p=gapil.git diff --git a/fileadv.tex b/fileadv.tex index 5fa13de..a7851b6 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -2732,7 +2732,7 @@ mappatura che gi -\subsection{I/O vettorizzato} +\subsection{I/O vettorizzato: \func{readv} e \func{writev}} \label{sec:file_multiple_io} Un caso abbastanza comune è quello in cui ci si trova a dover eseguire una @@ -2913,8 +2913,8 @@ delle prestazioni rispetto all'uso in sequenza di \func{read} e \func{write}, che possono essere fatte da una applicazione in user space che ha una maggiore conoscenza su come questi sono strutturati.} e che anzi in certi casi si avevano dei peggioramenti, questo ha portato alla -decisione\footnote{per le motivazioni di questa scelta si può fare riferimento - a quanto illustrato da Linus Torvalds in +decisione\footnote{per alcune motivazioni di questa scelta si può fare + riferimento a quanto illustrato da Linus Torvalds in \href{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html} {\texttt{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}}.} di consentire l'uso della funzione soltanto quando il file da cui si legge @@ -2924,20 +2924,85 @@ un errore di \errcode{EINVAL}. Nonostante i limiti illustrati resta comunque il dubbio se la scelta di disabilitare \func{sendfile} per il trasferimento di dati fra file di dati sia -davvero corretta; la funzione infatti se non altro consente di semplificare -l'interfaccia, evitando di dover gestire l'allocazione di un buffer temporaneo -per i trasferimenti dei dati in tutti quei casi in cui non c'è necessità -effettiva di fare controlli sugli stessi. Inoltre essa avrebbe comunque il -vantaggio di evitare trasferimenti di dati da e verso l'user space. +davvero corretta; la funzione infatti se non altro consentirebbe di +semplificare l'interfaccia per la copia dei dati, evitando di dover gestire +l'allocazione di un buffer temporaneo per il loro trasferimento in tutti quei +casi in cui non c'è necessità di fare controlli sugli stessi. Inoltre essa +avrebbe comunque il vantaggio di evitare trasferimenti di dati da e verso +l'user space. + +Il dubbio è stato rimosso con l'introduzione della system call +\func{splice},\footnote{avvenuto a partire dal kernel 2.6.17.} il cui scopo è +appunto quello di fornire un meccanismo generico per il trasferimento di dati +da o verso un file utilizzando un buffer intermedio gestito direttamente dal +kernel. Lo scopo della funzione può sembrare lo stesso di \func{sendfile}, ma +in realtà esse sono profondamente diverse nel loro meccanismo di +funzionamento; \func{sendfile} infatti, come accennato, non necessita affatto +(anzi nel caso di Linux viene sostanzialmente usata solo in questo caso) di +avere a disposizione un buffer interno, perché esegue un trasferimento diretto +di dati; questo la rende in generale molto più efficiente, ma anche limitata +nelle sue applicazioni. + +Il concetto che sta dietro a \func{splice} invece è diverso,\footnote{in + realtà la proposta originale di Larry Mc Voy non ne differisce poi tanto, + quello che la rende davvero diversa è stata la reinterpretazione che ne è + stata fatta nell'implementazione su Linux realizzata da Jens Anxboe, di cui + si può trovare un buon riassunto in \href{http://kerneltrap.org/node/6505} + {\texttt{http://kerneltrap.org/node/6505}}.} si tratta semplicemente di una +funzione che consente di fare delle operazioni di trasferimento dati da e +verso un buffer interamente gestito in kernel space, in maniera del tutto +generica. In questo caso il cuore della funzione (e delle affini +\func{vmsplice} e \func{tee}, che tratteremo più avanti) è appunto il buffer +in kernel space; questo è anche quello che ne ha semplificato +l'adozione,\footnote{la funzione infatti non è definita in nessuno standard, + e, allo stato attuale è disponibile soltanto su Linux.} perché +l'infrastruttura per la gestione di un buffer in kernel space è presente fin +dagli albori di Unix per la realizzazione delle \textit{pipe} (tratteremo +l'argomento in sez.~\ref{sec:ipc_unix}). Dal punto di vista concettuale allora +\func{splice} non è che un'altra interfaccia con cui esporre in userspace +l'oggetto \textsl{buffer in kernel space}. + +Così se per una \textit{pipe} o una \textit{fifo} il buffer viene utilizzato +come area di memoria dove appoggiare i dati che vengono trasferiti da un capo +all'altro della stessa (vedi fig.~\ref{fig:ipc_pipe_singular}) per creare un +meccanismo di comunicazione fra processi, nel caso di \funcd{splice} il buffer +viene usato o come fonte dei dati che saranno scritti su un file, o come +destinazione dei dati che vengono letti da un file. La funzione infatti è una +interfaccia generica che consente di trasferire dati da un buffer ad un file o +viceversa; il suo prototipo, accessibile solo avendo definito +\macro{\_GNU\_SOURCE},\footnote{ovviamente, essendo come detto la funzione + totalmente specifica di Linux, essa non è prevista da nessuno standard e + deve essere evitata se si vogliono scrivere programmi portabili.} è: +\begin{functions} + \headdecl{fcntl.h} + + \funcdecl{} + + Trasferisce dati da un file verso una pipe o viceversa. + + \bodydesc{La funzione restituisce il numero di byte trasferiti in caso di + successo e $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno + dei valori: + \begin{errlist} + \item[\errcode{EAGAIN}] si è impostata la modalità non bloccante su + \param{out\_fd} e la scrittura si bloccherebbe. + \item[\errcode{EINVAL}] i file descriptor non sono validi, o sono bloccati + (vedi sez.~\ref{sec:file_locking}), o \func{mmap} non è disponibile per + \param{in\_fd}. + \item[\errcode{EIO}] si è avuto un errore di lettura da \param{in\_fd}. + \item[\errcode{ENOMEM}] non c'è memoria sufficiente per la lettura da + \param{in\_fd}. + \end{errlist} + ed inoltre \errcode{EBADF} e \errcode{EFAULT}. + } +\end{functions} -Fino al 2.6.17 il problema % TODO documentare le funzioni tee e splice % http://kerneltrap.org/node/6505 e http://lwn.net/Articles/178199/ e % http://lwn.net/Articles/179492/ % e http://en.wikipedia.org/wiki/Splice_(system_call) -% e http://kerneltrap.org/node/6505