fa41648edbd995f56240865767dda6b724892dd1
[gapil.git] / fileadv.tex
1 \chapter{La gestione avanzata dei file}
2 \label{cha:file_advanced}
3
4 In questo capitolo affronteremo le tematiche relative alla gestione avanzata
5 dei file, che non sono state trattate in \capref{cha:file_unix_interface},
6 dove ci si è limitati ad una panoramica delle funzioni base. In particolare
7 tratteremo delle funzioni di input/output avanzato e del \textit{file
8   locking}.
9
10
11 \section{Le funzioni di I/O avanzato}
12 \label{sec:file_advanced_io}
13
14 In questa sezione esamineremo le funzioni che permettono una gestione più
15 sofisticata dell'I/O su file, a partire da quelle che permettono di gestire
16 l'accesso contemporaneo a più file, per concludere con la gestione dell'I/O
17 mappato in memoria.
18
19
20 \subsection{La modalità di I/O \textsl{non-bloccante}}
21 \label{sec:file_noblocking}
22
23 Abbiamo visto in \secref{sec:sig_gen_beha}, affrontando la suddivisione fra
24 \textit{fast} e \textit{slow} system call, che in certi casi le funzioni di
25 I/O possono bloccarsi indefinitamente.\footnote{si ricordi però che questo può
26   accadere solo per le pipe, i socket ed alcuni file di dispositivo; sui file
27   normali le funzioni di lettura e scrittura ritornano sempre subito.}  Ad
28 esempio le operazioni di lettura possono bloccarsi quando non ci sono dati
29 disponibili sul descrittore su cui si sta operando.
30
31 Uno dei problemi più comuni che ci si trova ad affrontare che non può essere
32 risolto con le funzioni base trattate in \capref{cha:file_unix_interface} è
33 quello in cui si devono eseguire su più di un file descriptor delle operazioni
34 che possono bloccarsi: il problema è che mentre si è bloccati su uno di questi
35 file su di un'altro potrebbero essere presenti dei dati.
36
37 Abbiamo già accennato in \secref{sec:file_open} che è possibile prevenire
38 questo tipo di comportamento aprendo un file in modalità
39 \textsl{non-bloccante}, specificando il flag \macro{O\_NONBLOCK} alla chiamata
40 di \func{open}. In questo caso le funzioni di input/output che altrimenti si
41 sarebbero bloccate ritornano immediatamente, restituendo l'errore
42 \macro{EAGAIN}.
43
44 L'utilizzo di questa modalità di I/O permette allora di risolvere il problema
45 controllando a turno i vari file descriptor, in un ciclo in cui si ripete
46 l'accesso fintanto che esso non viene garantito.  Ovviamente questa tecnica,
47 detta \textit{polling}, è estremamente inefficiente: si tiene costantemente
48 impiegata la CPU solo per eseguire in continuazione delle system call che
49 nella gran parte dei casi falliranno.
50
51 Per questo motivo, quando come vedremo in dettaglio in
52 \secref{sec:file_multiplexing}, il sistema fornisce delle funzioni apposite
53 che permettono di aggirare questo problema, permettendo di attendere fino alla
54 disponibilità di un accesso; per usarle però è comunque comunque necessario
55 utilizzare la modalità di I/O non bloccante.
56
57 \subsection{Le funzioni \func{poll} e \func{select}}
58 \label{sec:file_multiplexing}
59
60
61 %\section{I/O asincrono}
62 %\label{sec:file_asynchronous}
63
64 %Non supportato in Linux, in BSD e SRv4 c'è, ma usando il segnale \macro{SIGIO}
65 %per indicare che i dati sono disponibili, 
66
67 \subsection{L'I/O asincrono}
68 \label{sec:file_asyncronous_io}
69
70 Una modalità alternativa all'uso dell'I/O non bloccante è quella di fare
71 ricorso all'I/O asincrono. Abbiamo accennato in \secref{sec:file_open} che è
72 possibile, attraverso l'uso del flag \macro{O\_ASYNC}, aprire un file in
73 modalità asincrona, così come è possibile settare questo flag attraverso l'uso
74 di \func{fcntl}.
75
76 In tal caso il sistema genera un segnale \macro{SIGIO} tutte le volte che sono
77 presenti dei dati in input sul file.
78
79
80
81 Un dei problemi che si presentavano con le prime implementazioni di questa
82 modalità di I/O è che essa poteva essere usata in maniera semplice con un solo
83 file per processo, dato che altrimenti non sarebbe stato distinguere da quale
84 file proviene l'attività che ha causato l'emissione del segnale. 
85
86
87
88
89
90 \subsection{File mappati in memoria}
91 \label{sec:file_memory_map}
92
93
94 \subsection{I/O multiplo}
95 \label{sec:file_multiple_io}
96
97
98
99 \section{Il file locking}
100 \label{sec:file_locking}
101
102 In \secref{sec:file_sharing} abbiamo preso in esame le mosalità in cui un
103 sistema unix-like gestisce la condivisione dei file da parte di processi
104 diversi. In quell'occasione si è visto come, con l'eccezione dei file aperti
105 in \textit{append mode}, quando più processi scrivono contemporaneamente sullo
106 stesso file non è possibile determinare la sequenza in cui essi opereranno.
107
108 Questo causa la possibilità di race condition; in generale le situazioni più
109 comuni sono due: l'interazione fra un processo che scrive e altri che leggono,
110 in cui questi ultimi possono leggere informazioni scritte solo in maniera
111 parziale o incompleta; o quella in cui diversi processi scrivono, mescolando
112 in maniera imprevedebile il loro output sul file.
113
114 In tutti questi casi il \textit{file locking} è la tecnica che permette di
115 evitare le race condition, attraverso una serie di funzioni che permettono di
116 bloccare l'accesso al file da parte di altri processi, così da evitare le
117 sovrapposizioni, e garantire la atomicità delle operazioni di scrittura.
118
119
120 \subsection{L'\textit{advisory locking}}
121 \label{sec:file_record_locking}
122
123 La prima modalità di file locking che è stata implementata nei sistemi
124 unix-like è quella che viene usualmente chiamata \textit{advisory locking}, in
125 quanto è il processo, e non il sistema, che si incarica di verificare se
126 esiste una condizione di blocco per l'accesso ai file.
127
128
129
130
131 \subsection{Il \textit{mandatory locking}}
132 \label{sec:file_mand_locking}
133
134 Il \textit{mandatory locking} è una opzione introdotta inizialmente in SVr4, 
135
136
137
138
139
140
141 %%% Local Variables: 
142 %%% mode: latex
143 %%% TeX-master: "gapil"
144 %%% End: