X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileadv.tex;h=21dc922ac683c4fe499ff8d417a41bd0a91bb84c;hp=6737554729c23493928bed51931c1a4a9c911af8;hb=9c6ea14a2d89e1cb76b4dd8683542f71c9dcf107;hpb=525464ecdd7e6cbdccc733e73b5f1cc9dbe6022a diff --git a/fileadv.tex b/fileadv.tex index 6737554..21dc922 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -1,78 +1,107 @@ -\chapter{I/O avanzato} +\chapter{La gestione avanzata dei file} \label{cha:file_advanced} -In questo capitolo affronteremo le tematiche della gestione avanzata delle -funzioni di input/ouput, prenderemo in esame il \textit{file locking}, la -gestione dell'input/output da più file, per concludere con la gestione dei -file mappati in memoria. +In questo capitolo affronteremo le tematiche relative alla gestione avanzata +dei file, che non sono state trattate in \capref{cha:file_unix_interface}, +dove ci si è limitati ad una panoramica delle funzioni base. In particolare +tratteremo delle funzioni di input/output avanzato e del \textit{file + locking}. -\section{L'I/O avanzato} +\section{Le funzioni di I/O avanzato} \label{sec:file_advanced_io} -Uno dei problemi che ci si trova ad affrontare con le funzioni ordinarie -trattate in \capref{cha:file_unix_interface} è quello in cui si devono -eseguire su più di un file descriptor delle operazioni che possono bloccarsi: -il problema è che mentre si è bloccati su un file su di un'altro potrebbero -essere presenti dati da leggere. - -In questa sezione vedremo come si possono affrontare queste problematiche, -quali sono le soluzioni possibili e quali i meccanismi il kernel e le librerie -ci mettono a disposizione. +In questa sezione esamineremo le funzioni che permettono una gestione più +sofisticata dell'I/O su file, a partire da quelle che permettono di gestire +l'accesso contemporaneo a più file, per concludere con la gestione dell'I/O +mappato in memoria. \subsection{La modalità di I/O \textsl{non-bloccante}} \label{sec:file_noblocking} -Una prima soluzione per evitare di bloccarsi nelle operazioni di I/O è quella -di utilizzare la modalità \textsl{non-bloccante}. Abbiamo visto in -\secref{sec:sig_gen_beha}, affrontando la suddivisione fra \textit{fast} e -\textit{slow} system call, che in certi casi le funzioni di I/O possono -bloccarsi indefinitamente.\footnote{si ricordi però che questo può accadere - solo per le pipe, i socket ed alcuni file di dispositivo; sui file normali - le funzioni di lettura e scrittura ritornano sempre subito.} -In particolare le operazioni di lettura possono bloccarsi quando non ci sono -dati disponibili sul descrittore su cui si sta operando. +Abbiamo visto in \secref{sec:sig_gen_beha}, affrontando la suddivisione fra +\textit{fast} e \textit{slow} system call, che in certi casi le funzioni di +I/O possono bloccarsi indefinitamente.\footnote{si ricordi però che questo può + accadere solo per le pipe, i socket ed alcuni file di dispositivo; sui file + normali le funzioni di lettura e scrittura ritornano sempre subito.} Ad +esempio le operazioni di lettura possono bloccarsi quando non ci sono dati +disponibili sul descrittore su cui si sta operando. + +Uno dei problemi più comuni che ci si trova ad affrontare, che non può essere +risolto con le funzioni di base trattate in \capref{cha:file_unix_interface}, +è quello in cui si devono eseguire operazioni che possono bloccarsi su più +file descriptor: il problema è che mentre si è bloccati su uno di questi file +su di un'altro potrebbero essere presenti dei dati, così che nel migliore dei +casi si avrebbe una lettura inutilmente ritardata, e nel peggiore si potrebbe +addirittura arrivare ad un deadlock. Abbiamo già accennato in \secref{sec:file_open} che è possibile prevenire -questo tipo di comportamento aprendo il file in modalità non bloccante, -specificando il flag \macro{O\_NONBLOCK}. In questo caso le funzioni che si -sarebbero bloccate ritornano immediatamente restituendo l'errore +questo tipo di comportamento aprendo un file in modalità +\textsl{non-bloccante}, specificando il flag \macro{O\_NONBLOCK} alla chiamata +di \func{open}. In questo caso le funzioni di input/output che altrimenti si +sarebbero bloccate ritornano immediatamente, restituendo l'errore \macro{EAGAIN}. -L'utilizzo di questa modalità di I/O permette allora di risolvere il problema +L'utilizzo di questa modalità di I/O permette allora 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}, è estremamente inefficiente: si tiene costantemente +impiegata la CPU solo per eseguire in continuazione delle system call che +nella gran parte dei casi falliranno. + +Per questo motivo, quando come vedremo in dettaglio in +\secref{sec:file_multiplexing}, il sistema fornisce delle funzioni apposite +che permettono di aggirare questo problema, permettendo di attendere fino alla +disponibilità di un accesso; per poterle usare però è comunque comunque +necessario utilizzare la modalità di I/O non bloccante all'apertura del file. +\subsection{Le funzioni \func{poll} e \func{select}} +\label{sec:file_multiplexing} -%\section{I/O asincrono} -%\label{sec:file_asynchronous} -%Non supportato in Linux, in BSD e SRv4 c'è, ma usando il segnale \macro{SIGIO} -%per indicare che i dati sono disponibili, può essere usato in maniera semplice -%con un solo file per processo (altrimenti non sarebbe più possibile -%distinguere da quale file proviene l'attività che ha causato l'emissione del -%segnale). \subsection{L'I/O asincrono} \label{sec:file_asyncronous_io} +Una modalità alternativa all'uso dell'I/O non bloccante è quella di fare +ricorso all'I/O asincrono. Abbiamo accennato in \secref{sec:file_open} che è +possibile, attraverso l'uso del flag \macro{O\_ASYNC}, aprire un file in +modalità asincrona, così come è possibile settare questo flag attraverso l'uso +di \func{fcntl}. +In tal caso il sistema genera un segnale \macro{SIGIO} tutte le volte che sono +presenti dei dati in input su un file aperto in questa modalità. Uno dei +problemi che si presentavano con le prime implementazioni di questa modalità +di I/O è che essa poteva essere usata in maniera semplice aprendo un solo file +per processo, dato che altrimenti si sarebbe dovuto provvedere ad effettuare +una serie di controlli su tutti i file aperti per distinguere a quale fosse +dovuto l'emissione del segnale. -\subsection{Le funzioni \func{poll} e \func{select}} -\label{sec:file_multiplexing} +Tutto questo adesso può essere evitato facendo ricorso alle informazioni +restituite al manipolatore del segnale attraverso la struttura +\var{siginfo\_t} (vedi \figref{fig:sig_siginfo_t}), il cui campo \var{si\_fd} +riporta il file descriptor che ha generato il segnale. +\subsection{File mappati in memoria} +\label{sec:file_memory_map} + + +\subsection{I/O multiplo} +\label{sec:file_multiple_io} -\section{File locking} +\section{Il file locking} \label{sec:file_locking} In \secref{sec:file_sharing} abbiamo preso in esame le mosalità in cui un -sistema unix-like gestisce la condivisione dei file. In quell'occasione si è -visto come, con l'eccezione dei file aperti in \textit{append mode}, quando -più processi scrivono contemporaneamente sullo stesso file non è possibile -determinare la sequenza in cui essi opereranno. +sistema unix-like gestisce la condivisione dei file da parte di processi +diversi. In quell'occasione si è visto come, con l'eccezione dei file aperti +in \textit{append mode}, quando più processi scrivono contemporaneamente sullo +stesso file non è possibile determinare la sequenza in cui essi opereranno. Questo causa la possibilità di race condition; in generale le situazioni più comuni sono due: l'interazione fra un processo che scrive e altri che leggono, @@ -82,11 +111,11 @@ in maniera imprevedebile il loro output sul file. In tutti questi casi il \textit{file locking} è la tecnica che permette di evitare le race condition, attraverso una serie di funzioni che permettono di -bloccare l'accesso al file da parte di altri processi così da evitare le +bloccare l'accesso al file da parte di altri processi, così da evitare le sovrapposizioni, e garantire la atomicità delle operazioni di scrittura. -\subsection{Il \textit{advisory locking}} +\subsection{L'\textit{advisory locking}} \label{sec:file_record_locking} La prima modalità di file locking che è stata implementata nei sistemi @@ -100,14 +129,11 @@ esiste una condizione di blocco per l'accesso ai file. \subsection{Il \textit{mandatory locking}} \label{sec:file_mand_locking} -Il \textit{mandatory locking} è una opzione introdotta inizialmente in SVR4, +Il \textit{mandatory locking} è una opzione introdotta inizialmente in SVr4, -\section{File mappati in memoria} -\label{sec:file_memory_map} - %%% Local Variables: