X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileadv.tex;h=1581fbb97b146a1b5fb07e75af4549b850fc0b84;hp=5fa13de21efd25ed84475cd07b761ef62077f965;hb=eba75c4aaf390ff55ad6697ab80d4c1512ea2f39;hpb=d451ac30382ae398b9a2242a4f82b3438affc8a7 diff --git a/fileadv.tex b/fileadv.tex index 5fa13de..1581fbb 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,62 @@ 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 illustrato in fig.~\ref{fig:ipc_pipe_singular}) come area di memoria +dove appoggiare i dati che vengono trasferiti da un capo all'altro della +stessa, creando un meccanismo di comunicazione fra processi, nel caso di +\func{splice} il buffer viene usato o come fonte dei dati che con saranno +scritti su un file, o come destinazione dei dati che vengono letti da un file. + + + + + -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