%% fileadv.tex
%%
-%% Copyright (C) 2000-2006 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2007 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
possibile prevedere quando questo può avvenire (il caso più classico è quello
di un server in attesa di dati in ingresso da vari client). Quello che può
accadere è di restare bloccati nell'eseguire una operazione su un file
-descriptor che non è ``\textsl{pronto}'', quando ce ne potrebbe essere
-un altro disponibile. Questo comporta nel migliore dei casi una operazione
+descriptor che non è ``\textsl{pronto}'', quando ce ne potrebbe essere un
+altro disponibile. Questo comporta nel migliore dei casi una operazione
ritardata inutilmente nell'attesa del completamento di quella bloccata, mentre
nel peggiore dei casi (quando la conclusione della operazione bloccata dipende
da quanto si otterrebbe dal file descriptor ``\textsl{disponibile}'') si
-potrebbe addirittura arrivare ad un \textit{deadlock}\itindex{deadlock}.
+potrebbe addirittura arrivare ad un \itindex{deadlock} \textit{deadlock}.
Abbiamo già accennato in sez.~\ref{sec:file_open} che è possibile prevenire
questo tipo di comportamento delle funzioni di I/O aprendo un file in
restituendo l'errore \errcode{EAGAIN}. L'utilizzo di questa modalità di I/O
permette di risolvere il problema controllando a turno i vari file descriptor,
in un ciclo in cui si ripete l'accesso fintanto che esso non viene garantito.
-Ovviamente questa tecnica, detta \textit{polling}\itindex{polling}, è
+Ovviamente questa tecnica, detta \itindex{polling} \textit{polling}, è
estremamente inefficiente: si tiene costantemente impiegata la CPU solo per
eseguire in continuazione delle system call che nella gran parte dei casi
falliranno.
grafica) sono state successivamente introdotte delle estensioni che
permettessero la creazione di meccanismi di notifica più efficienti dell'unica
soluzione disponibile con l'interfaccia tradizionale, che è quella del
-\itindex{polling}\textit{polling}.
+\itindex{polling} \textit{polling}.
Queste nuove funzionalità sono delle estensioni specifiche, non
standardizzate, che sono disponibili soltanto su Linux (anche se altri kernel
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}system call lente), essa è
+le funzioni di I/O sono \index{system~call~lente} 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
Una modalità alternativa di I/O, che usa una interfaccia completamente diversa
rispetto a quella classica vista in cap.~\ref{cha:file_unix_interface}, è il
cosiddetto \textit{memory-mapped I/O}, che, attraverso il meccanismo della
-\textsl{paginazione}\index{paginazione} usato dalla memoria virtuale (vedi
+\textsl{paginazione} \index{paginazione} usato dalla memoria virtuale (vedi
sez.~\ref{sec:proc_mem_gen}), permette di \textsl{mappare} il contenuto di un
file in una sezione dello spazio di indirizzi del processo.
file viene \textsl{mappata} direttamente nello spazio degli indirizzi del
programma. Tutte le operazioni di lettura e scrittura su variabili contenute
in questa zona di memoria verranno eseguite leggendo e scrivendo dal contenuto
-del file attraverso il sistema della memoria virtuale\index{memoria~virtuale}
+del file attraverso il sistema della memoria virtuale \index{memoria~virtuale}
che in maniera analoga a quanto avviene per le pagine che vengono salvate e
rilette nella swap, si incaricherà di sincronizzare il contenuto di quel
segmento di memoria con quello del file mappato su di esso. Per questo motivo
di caricare in memoria solo le parti del file che sono effettivamente usate ad
un dato istante.
-Infatti, dato che l'accesso è fatto direttamente attraverso la memoria
-virtuale,\index{memoria~virtuale} la sezione di memoria mappata su cui si
-opera sarà a sua volta letta o scritta sul file una pagina alla volta e solo
-per le parti effettivamente usate, il tutto in maniera completamente
+Infatti, dato che l'accesso è fatto direttamente attraverso la
+\index{memoria~virtuale} memoria virtuale, la sezione di memoria mappata su
+cui si opera sarà a sua volta letta o scritta sul file una pagina alla volta e
+solo per le parti effettivamente usate, il tutto in maniera completamente
trasparente al processo; l'accesso alle pagine non ancora caricate avverrà
allo stesso modo con cui vengono caricate in memoria le pagine che sono state
salvate sullo swap.
privata cui solo il processo chiamante ha
accesso. Le modifiche sono mantenute attraverso
il meccanismo del \textit{copy on
- write}\itindex{copy~on~write} e
+ write} \itindex{copy~on~write} e
salvate su swap in caso di necessità. Non è
specificato se i cambiamenti sul file originale
vengano riportati sulla regione
mappata. Incompatibile con \const{MAP\_SHARED}. \\
\const{MAP\_DENYWRITE} & In Linux viene ignorato per evitare
- \textit{DoS}\itindex{Denial~of~Service~(DoS)}
+ \textit{DoS} \itindex{Denial~of~Service~(DoS)}
(veniva usato per segnalare che tentativi di
scrittura sul file dovevano fallire con
\errcode{ETXTBSY}).\\
\const{MAP\_EXECUTABLE}& Ignorato. \\
\const{MAP\_NORESERVE} & Si usa con \const{MAP\_PRIVATE}. Non riserva
delle pagine di swap ad uso del meccanismo del
- \textit{copy on write}\itindex{copy~on~write}
+ \textit{copy on write} \itindex{copy~on~write}
per mantenere le
modifiche fatte alla regione mappata, in
questo caso dopo una scrittura, se non c'è più
Gli effetti dell'accesso ad una zona di memoria mappata su file possono essere
piuttosto complessi, essi si possono comprendere solo tenendo presente che
-tutto quanto è comunque basato sul meccanismo della memoria
-virtuale.\index{memoria~virtuale} Questo comporta allora una serie di
-conseguenze. La più ovvia è che se si cerca di scrivere su una zona mappata in
-sola lettura si avrà l'emissione di un segnale di violazione di accesso
-(\const{SIGSEGV}), dato che i permessi sul segmento di memoria relativo non
-consentono questo tipo di accesso.
+tutto quanto è comunque basato sul meccanismo della \index{memoria~virtuale}
+memoria virtuale. Questo comporta allora una serie di conseguenze. La più
+ovvia è che se si cerca di scrivere su una zona mappata in sola lettura si
+avrà l'emissione di un segnale di violazione di accesso (\const{SIGSEGV}),
+dato che i permessi sul segmento di memoria relativo non consentono questo
+tipo di accesso.
È invece assai diversa la questione relativa agli accessi al di fuori della
regione di cui si è richiesta la mappatura. A prima vista infatti si potrebbe
ritenere che anch'essi debbano generare un segnale di violazione di accesso;
questo però non tiene conto del fatto che, essendo basata sul meccanismo della
-paginazione\index{paginazione}, la mappatura in memoria non può che essere
+paginazione \index{paginazione}, la mappatura in memoria non può che essere
eseguita su un segmento di dimensioni rigorosamente multiple di quelle di una
pagina, ed in generale queste potranno non corrispondere alle dimensioni
-effettive del file o della sezione che si vuole mappare.
+effettive del file o della sezione che si vuole mappare.
\footnotetext[20]{Dato che tutti faranno riferimento alle stesse pagine di
memoria.}
output sul file.
In tutti questi casi il \textit{file locking} è la tecnica che permette di
-evitare le \textit{race condition}\itindex{race~condition}, attraverso una
+evitare le \textit{race condition} \itindex{race~condition}, attraverso una
serie di funzioni che permettono di bloccare l'accesso al file da parte di
altri processi, così da evitare le sovrapposizioni, e garantire la atomicità
delle operazioni di scrittura.
\item[\errcode{EDEADLK}] Si è richiesto un lock su una regione bloccata da
un altro processo che è a sua volta in attesa dello sblocco di un lock
mantenuto dal processo corrente; si avrebbe pertanto un
- \textit{deadlock}\itindex{deadlock}. Non è garantito che il sistema
+ \itindex{deadlock} \textit{deadlock}. Non è garantito che il sistema
riconosca sempre questa situazione.
\item[\errcode{EINTR}] La funzione è stata interrotta da un segnale prima
di poter acquisire un lock.
\begin{figure}[htb]
\centering \includegraphics[width=9cm]{img/file_lock_dead}
- \caption{Schema di una situazione di \textit{deadlock}\itindex{deadlock}.}
+ \caption{Schema di una situazione di \itindex{deadlock} \textit{deadlock}.}
\label{fig:file_flock_dead}
\end{figure}
del processo 2; il processo 1 si bloccherà fintanto che il processo 2 non
rilasci il blocco. Ma cosa accade se il processo 2 nel frattempo tenta a sua
volta di ottenere un lock sulla regione A? Questa è una tipica situazione che
-porta ad un \textit{deadlock}\itindex{deadlock}, dato che a quel punto anche
+porta ad un \itindex{deadlock} \textit{deadlock}, dato che a quel punto anche
il processo 2 si bloccherebbe, e niente potrebbe sbloccare l'altro processo.
Per questo motivo il kernel si incarica di rilevare situazioni di questo tipo,
ed impedirle restituendo un errore di \errcode{EDEADLK} alla funzione che
-cerca di acquisire un lock che porterebbe ad un \textit{deadlock}.
+cerca di acquisire un lock che porterebbe ad un \itindex{deadlock}
+\textit{deadlock}.
\begin{figure}[!bht]
\centering \includegraphics[width=13cm]{img/file_posix_lock}
bloccata grazie ai campi \var{fl\_start} e \var{fl\_end}. La struttura è
comunque la stessa, solo che in questo caso nel campo \var{fl\_flags} è
impostato il bit \const{FL\_POSIX} ed il campo \var{fl\_file} non viene
- usato.} il lock è sempre associato all'inode\index{inode}, solo che in
+ usato.} il lock è sempre associato \index{inode} all'inode, solo che in
questo caso la titolarità non viene identificata con il riferimento ad una
voce nella \itindex{file~table} \textit{file table}, ma con il valore del
\acr{pid} del processo.
soltanto quando si chiama \func{mmap} con l'opzione \const{MAP\_SHARED} (nel
qual caso la funzione fallisce con il solito \errcode{EAGAIN}) che comporta la
possibilità di modificare il file.
-\index{file!locking|)}
-\itindend{mandatory~locking|(}
+\index{file!locking|)}
+\itindend{mandatory~locking|(}
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "gapil"
-%%% End:
-
% LocalWords: dell'I locking multiplexing cap dell' sez system call socket BSD
% LocalWords: descriptor client deadlock NONBLOCK EAGAIN polling select kernel
% LocalWords: pselect like sys unistd int fd readfds writefds exceptfds struct
% LocalWords: EDEADLK whence SEEK CUR type pid GETLK SETLK SETLKW all'inode HP
% LocalWords: switch bsd lockf mandatory SVr sgid group root mount mand TRUNC
% LocalWords: SVID UX Documentation sendfile
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: