Aggiunte varie e correzioni
authorSimone Piccardi <piccardi@gnulinux.it>
Fri, 1 Jan 2010 22:48:24 +0000 (22:48 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Fri, 1 Jan 2010 22:48:24 +0000 (22:48 +0000)
fileadv.tex

index 117d9b93a16f4472ec01ddf20e9483b85c53f09c..97249198be36d745d604947117032ff1c642b114 100644 (file)
@@ -3878,19 +3878,24 @@ ma si perder
 
 Si tenga presente infine che queste funzioni operano sui file con
 l'interfaccia dei file descriptor, e non è consigliabile mescolarle con
 
 Si tenga presente infine che queste funzioni operano sui file con
 l'interfaccia dei file descriptor, e non è consigliabile mescolarle con
-l'interfaccia classica dei \textit{file stream}; a causa delle bufferizzazioni
-interne di quest'ultima infatti si potrebbero avere risultati indefiniti e non
-corrispondenti a quanto aspettato. 
+l'interfaccia classica dei \textit{file stream} di
+cap.~\ref{cha:files_std_interface}; a causa delle bufferizzazioni interne di
+quest'ultima infatti si potrebbero avere risultati indefiniti e non
+corrispondenti a quanto aspettato.
 
 Come per le normali operazioni di lettura e scrittura, anche per l'\textsl{I/O
   vettorizzato} si pone il problema di poter effettuare le operazioni in
 
 Come per le normali operazioni di lettura e scrittura, anche per l'\textsl{I/O
   vettorizzato} si pone il problema di poter effettuare le operazioni in
-maniera atomica a partire da un certa posizione sul file, così da evitare
-eventuali \itindex{race~condition} \textit{race conditions} in caso di
-combinazione con l'uso di \func{lseek}. Per questo motivo a partire dal kernel
-2.6.30 sono state introdotte anche per l'\textsl{I/O vettorizzato} le analoghe
-delle funzioni \func{pread} e \func{pwrite} (vedi sez.~\ref{sec:file_read} e
-\ref{sec:file_write}); le due funzioni sono \funcd{preadv} e \func{pwritev} ed
-i rispettivi prototipi sono:
+maniera atomica a partire da un certa posizione sul file. Per questo motivo a
+partire dal kernel 2.6.30 sono state introdotte anche per l'\textsl{I/O
+  vettorizzato} le analoghe delle funzioni \func{pread} e \func{pwrite} (vedi
+sez.~\ref{sec:file_read} e \ref{sec:file_write}); le due funzioni sono
+\funcd{preadv} e \func{pwritev} ed i rispettivi prototipi sono:\footnote{le
+  due funzioni sono analoghe alle omonime presenti in BSD; le \textit{system
+    call} usate da Linux (introdotte a partire dalla versione 2.6.30)
+  utilizzano degli argomenti diversi per problemi collegati al formato a 64
+  bit dell'argomento \param{offset}, che varia a seconda delle architetture,
+  ma queste differenze vengono gestite dalle funzioni di librerie di libreria
+  che mantengono l'interfaccia delle analoghe tratte da BSD.}
 \begin{functions}
   \headdecl{sys/uio.h}
   
 \begin{functions}
   \headdecl{sys/uio.h}
   
@@ -3902,8 +3907,10 @@ i rispettivi prototipi sono:
   Eseguono una lettura o una scrittura vettorizzata a partire da una data
   posizione sul file.
   
   Eseguono una lettura o una scrittura vettorizzata a partire da una data
   posizione sul file.
   
-  \bodydesc{Le funzioni hanno gli stessi valori di ritorno e gli stessi errori
-    delle corrispondenti \func{readv} e \func{writev} a cui si può aggiungere:
+  \bodydesc{Le funzioni hanno gli stessi valori di ritorno delle
+    corrispondenti \func{readv} e \func{writev}; anche gli eventuali errori
+    sono gli stessi già visti in precedenza, ma ad essi si possono aggiungere
+    per \var{errno} anche i valori:
   \begin{errlist}
   \item[\errcode{EOVERFLOW}] \param{offset} ha un valore che non può essere
     usato come \ctyp{off\_t}.
   \begin{errlist}
   \item[\errcode{EOVERFLOW}] \param{offset} ha un valore che non può essere
     usato come \ctyp{off\_t}.
@@ -3912,8 +3919,20 @@ i rispettivi prototipi sono:
 }
 \end{functions}
 
 }
 \end{functions}
 
-% TODO preadv e pwritev inserite nel kernel 2.6.30, vedi
-% http://lwn.net/Articles/326818/ 
+Le due funzioni eseguono rispettivamente una lettura o una scrittura
+vettorizzata a partire dalla posizione \param{offset} sul file indicato
+da \param{fd}, la posizione corrente sul file, come vista da eventuali altri
+processi che vi facciano riferimento, non viene alterata. A parte la presenza
+dell'ulteriore argomento il comportamento delle funzioni è identico alle
+precedenti \func{readv} e \func{writev}. 
+
+Con l'uso di queste funzioni si possono evitare eventuali
+\itindex{race~condition} \textit{race conditions} quando si deve eseguire la
+una operazione di lettura e scrittura vettorizzata a partire da una certa
+posizione su un file, mentre al contempo si possono avere in concorrenza
+processi che utilizzano lo stesso file descriptor (si ricordi quanto visto in
+sez.~\ref{sec:file_adv_func}) con delle chiamate a \func{lseek}.
+
 
 
 \subsection{L'I/O diretto fra file descriptor: \func{sendfile} e
 
 
 \subsection{L'I/O diretto fra file descriptor: \func{sendfile} e
@@ -3933,15 +3952,15 @@ efficiente mantenere tutto in kernel space. Tratteremo in questa sezione
 alcune funzioni specialistiche che permettono di ottimizzare le prestazioni in
 questo tipo di situazioni.
 
 alcune funzioni specialistiche che permettono di ottimizzare le prestazioni in
 questo tipo di situazioni.
 
-La prima funzione che si pone l'obiettivo di ottimizzare il trasferimento dei
-dati fra due file descriptor è \funcd{sendfile};\footnote{la funzione è stata
+La prima funzione che è stata ideata per ottimizzare il trasferimento dei dati
+fra due file descriptor è \func{sendfile};\footnote{la funzione è stata
   introdotta con i kernel della serie 2.2, e disponibile dalle \acr{glibc}
   2.1.} la funzione è presente in diverse versioni di Unix,\footnote{la si
   ritrova ad esempio in FreeBSD, HPUX ed altri Unix.} ma non è presente né in
 POSIX.1-2001 né in altri standard,\footnote{pertanto si eviti di utilizzarla
   se si devono scrivere programmi portabili.} per cui per essa vengono
   introdotta con i kernel della serie 2.2, e disponibile dalle \acr{glibc}
   2.1.} la funzione è presente in diverse versioni di Unix,\footnote{la si
   ritrova ad esempio in FreeBSD, HPUX ed altri Unix.} ma non è presente né in
 POSIX.1-2001 né in altri standard,\footnote{pertanto si eviti di utilizzarla
   se si devono scrivere programmi portabili.} per cui per essa vengono
-utilizzati prototipi e semantiche differenti; nel caso di Linux il suo
-prototipo è:
+utilizzati prototipi e semantiche differenti; nel caso di Linux il prototipo
+di \funcd{sendfile} è:
 \begin{functions}  
   \headdecl{sys/sendfile.h} 
 
 \begin{functions}  
   \headdecl{sys/sendfile.h} 
 
@@ -3970,7 +3989,7 @@ prototipo 
 La funzione copia direttamente \param{count} byte dal file descriptor
 \param{in\_fd} al file descriptor \param{out\_fd}; in caso di successo
 funzione ritorna il numero di byte effettivamente copiati da \param{in\_fd} a
 La funzione copia direttamente \param{count} byte dal file descriptor
 \param{in\_fd} al file descriptor \param{out\_fd}; in caso di successo
 funzione ritorna il numero di byte effettivamente copiati da \param{in\_fd} a
-\param{out\_fd} o $-1$ in caso di errore, come le ordinarie \func{read} e
+\param{out\_fd} o $-1$ in caso di errore; come le ordinarie \func{read} e
 \func{write} questo valore può essere inferiore a quanto richiesto con
 \param{count}.
 
 \func{write} questo valore può essere inferiore a quanto richiesto con
 \param{count}.
 
@@ -4018,19 +4037,16 @@ non 
 casi l'uso di \func{sendfile} darà luogo ad un errore di \errcode{EINVAL}.
 
 Nonostante ci possano essere casi in cui \func{sendfile} non migliora le
 casi l'uso di \func{sendfile} darà luogo ad un errore di \errcode{EINVAL}.
 
 Nonostante ci possano essere casi in cui \func{sendfile} non migliora le
-prestazioni, le motivazioni addotte non convincono del tutto e resta il dubbio
-se la scelta di disabilitarla sempre per il trasferimento di dati fra file di
-dati sia davvero corretta. Se ci sono peggioramenti di prestazioni infatti si
-può sempre fare ricorso all'uso successivo di, ma lasciare a disposizione la
-funzione consentirebbe se non altro, anche in assenza di guadagni di
-prestazioni, di semplificare la gestione della copia dei dati fra file,
-evitando di dover gestire l'allocazione di un buffer temporaneo per il loro
-trasferimento; inoltre si avrebbe comunque il vantaggio di evitare inutili
-trasferimenti di dati da kernel space a user space e viceversa.
-
-Questo dubbio si può comunque ritenere superato con l'introduzione, avvenuto a
-partire dal kernel 2.6.17, della nuova system call \func{splice}. Lo scopo di
-questa funzione è quello di fornire un meccanismo generico per il
+prestazioni, resta il dubbio se la scelta di disabilitarla sempre per il
+trasferimento fra file di dati sia davvero corretta. Se ci sono peggioramenti
+di prestazioni infatti si può sempre fare ricorso al metodo ordinario, ma
+lasciare a disposizione la funzione consentirebbe se non altro di semplificare
+la gestione della copia dei dati fra file, evitando di dover gestire
+l'allocazione di un buffer temporaneo per il loro trasferimento.
+
+Questo dubbio si può comunque ritenere superato con l'introduzione, avvenuta a
+partire dal kernel 2.6.17, della nuova \textit{system call} \func{splice}. Lo
+scopo di questa funzione è quello di fornire un meccanismo generico per il
 trasferimento di dati da o verso un file utilizzando un buffer gestito
 internamente dal kernel. Descritta in questi termini \func{splice} sembra
 semplicemente un ``\textsl{dimezzamento}'' di \func{sendfile}.\footnote{nel
 trasferimento di dati da o verso un file utilizzando un buffer gestito
 internamente dal kernel. Descritta in questi termini \func{splice} sembra
 semplicemente un ``\textsl{dimezzamento}'' di \func{sendfile}.\footnote{nel
@@ -4192,16 +4208,17 @@ descrizioni complete di tutti i valori possibili anche quando, come per
   \label{tab:splice_flag}
 \end{table}
 
   \label{tab:splice_flag}
 \end{table}
 
-\footnotetext{per una maggiore efficienza \func{splice} usa quando possibile i
-  meccanismi della memoria virtuale per eseguire i trasferimenti di dati (in
-  maniera analoga a \func{mmap}), qualora le pagine non possano essere
-  spostate dalla pipe o il buffer non corrisponda a pagine intere esse saranno
-  comunque copiate.}
+\footnotetext[120]{per una maggiore efficienza \func{splice} usa quando
+  possibile i meccanismi della memoria virtuale per eseguire i trasferimenti
+  di dati (in maniera analoga a \func{mmap}), qualora le pagine non possano
+  essere spostate dalla pipe o il buffer non corrisponda a pagine intere esse
+  saranno comunque copiate.}
 
 
-\footnotetext{questa opzione consente di utilizzare delle opzioni di gestione
-  dei socket che permettono di ottimizzare le trasmissioni via rete, si veda
-  la descrizione di \const{TCP\_CORK} in sez.~\ref{sec:sock_tcp_udp_options} e
-  quella di \const{MSG\_MORE} in sez.~\ref{sec:net_sendmsg}.}
+\footnotetext[121]{questa opzione consente di utilizzare delle opzioni di
+  gestione dei socket che permettono di ottimizzare le trasmissioni via rete,
+  si veda la descrizione di \const{TCP\_CORK} in
+  sez.~\ref{sec:sock_tcp_udp_options} e quella di \const{MSG\_MORE} in
+  sez.~\ref{sec:net_sendmsg}.}
 
 \footnotetext{questo significa che la cache delle pagine e i dati su disco
   potranno differire, e che l'applicazione non potrà modificare quest'area di
 
 \footnotetext{questo significa che la cache delle pagine e i dati su disco
   potranno differire, e che l'applicazione non potrà modificare quest'area di
@@ -4307,7 +4324,8 @@ descriptor, le tratteremo qui.
 
 La prima funzione, \funcd{vmsplice}, è la più simile a \func{splice} e come
 indica il suo nome consente di trasferire i dati dalla memoria di un processo
 
 La prima funzione, \funcd{vmsplice}, è la più simile a \func{splice} e come
 indica il suo nome consente di trasferire i dati dalla memoria di un processo
-verso una \textit{pipe}, il suo prototipo è:
+(ad esempio per un file mappato in memoria) verso una \textit{pipe}, il suo
+prototipo è:
 \begin{functions}  
   \headdecl{fcntl.h} 
   \headdecl{sys/uio.h}
 \begin{functions}  
   \headdecl{fcntl.h} 
   \headdecl{sys/uio.h}
@@ -4331,21 +4349,25 @@ verso una \textit{pipe}, il suo prototipo 
   }
 \end{functions}
 
   }
 \end{functions}
 
-La \textit{pipe} dovrà essere specificata tramite il file descriptor
-corrispondente al suo capo aperto in scrittura (di nuovo si faccia riferimento
-a sez.~\ref{sec:ipc_unix}), mentre per indicare quali zone di memoria devono
-essere trasferita si deve utilizzare un vettore di strutture \struct{iovec}
-(vedi fig.~\ref{fig:file_iovec}), con le stesse con cui le si usano per l'I/O
-vettorizzato; le dimensioni del suddetto vettore devono essere passate
+La \textit{pipe} indicata da \param{fd} dovrà essere specificata tramite il
+file descriptor corrispondente al suo capo aperto in scrittura (di nuovo si
+faccia riferimento a sez.~\ref{sec:ipc_unix}), mentre per indicare quali zone
+di memoria devono essere trasferita si dovrà utilizzare un vettore di
+strutture \struct{iovec} (vedi fig.~\ref{fig:file_iovec}), esattamente con gli
+stessi criteri con cui le si usano per l'I/O vettorizzato, indicando gli
+indirizzi e le dimensioni di ciascun segmento di memoria su cui si vuole
+operare; le dimensioni del suddetto vettore devono essere passate
 nell'argomento \param{nr\_segs} che indica il numero di segmenti di memoria da
 trasferire.  Sia per il vettore che per il valore massimo di \param{nr\_segs}
 valgono le stesse limitazioni illustrate in sez.~\ref{sec:file_multiple_io}.
 
 In caso di successo la funzione ritorna il numero di byte trasferiti sulla
 nell'argomento \param{nr\_segs} che indica il numero di segmenti di memoria da
 trasferire.  Sia per il vettore che per il valore massimo di \param{nr\_segs}
 valgono le stesse limitazioni illustrate in sez.~\ref{sec:file_multiple_io}.
 
 In caso di successo la funzione ritorna il numero di byte trasferiti sulla
-pipe, in generale (se i dati una volta creati non devono essere riutilizzati)
-è opportuno utilizzare il flag \const{SPLICE\_F\_GIFT}; questo fa si che il
-kernel possa rimuovere le relative pagine dallo spazio degli indirizzi del
-processo, e scaricarle nella cache, così che queste possono essere utilizzate
+\textit{pipe}. In generale, se i dati una volta creati non devono essere
+riutilizzati (se cioè l'applicazione che chiama \func{vmsplice} non
+modificherà più la memoria trasferita), è opportuno utilizzare
+per \param{flag} il valore \const{SPLICE\_F\_GIFT}; questo fa sì che il kernel
+possa rimuovere le relative pagine dallo spazio degli indirizzi del processo,
+e scaricarle nella cache, così che queste possono essere utilizzate
 immediatamente senza necessità di eseguire una copia dei dati che contengono.
 
 La seconda funzione aggiunta insieme a \func{splice} è \func{tee}, che deve il
 immediatamente senza necessità di eseguire una copia dei dati che contengono.
 
 La seconda funzione aggiunta insieme a \func{splice} è \func{tee}, che deve il