From: Simone Piccardi Date: Sun, 26 May 2002 09:58:52 +0000 (+0000) Subject: Iniziato I/O avanzato X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=1639f660dadb609be0b033750075cab883bdd0b4 Iniziato I/O avanzato --- diff --git a/fileadv.tex b/fileadv.tex index 697a941..b27f34e 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -3,27 +3,45 @@ In questo capitolo affronteremo le tematiche della gestione avanzata delle funzioni di input/ouput, prenderemo in esame il \textit{file locking}, la -gestione dell'I/O non bloccante e multiplexato, per concludere con la gestione -dei file mappati in memoria. +gestione dell'input/output da più file, per concludere con la gestione dei +file mappati in memoria. +\section{L'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 un'altro potrebbe essere +libero. -\section{File locking} -\label{sec:file_locking} - +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. -\subsection{Il \textit{mandatory locking}} -\label{sec:file_mand_locking} +\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. -\section{I/O non bloccante} -\label{sec:file_noblocking} +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 +\macro{EAGAIN}. +Esistono molti casi però in cui non si vuole che questo avvenga -\section{I/O multiplexato} -\label{sec:file_multiplexing} %\section{I/O asincrono} @@ -35,6 +53,58 @@ dei file mappati in memoria. %distinguere da quale file proviene l'attività che ha causato l'emissione del %segnale). +\subsection{L'I/O asincrono} +\label{sec:file_asyncronous_io} + + + +\subsection{Le funzioni \func{poll} e \func{select}} +\label{sec:file_multiplexing} + + + + + + +\section{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. + +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, +in cui questi ultimi possono leggere informazioni scritte solo in maniera +parziale o incompleta; o quella in cui diversi processi scrivono, mescolando +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 +sovrapposizioni, e garantire la atomicità delle operazioni di scrittura. + + +\subsection{Il \textit{advisory locking}} +\label{sec:file_record_locking} + +La prima modalità di file locking che è stata implementata nei sistemi +unix-like è quella che viene usualmente chiamata \textit{advisory locking}, in +quanto è il processo, e non il sistema, che si incarica di verificare se +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, + + + \section{File mappati in memoria} \label{sec:file_memory_map} diff --git a/fileunix.tex b/fileunix.tex index 0551441..5cef3d2 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -264,8 +264,8 @@ sempre il file descriptor con il valore pi file. Può causare corruzione del file con NFS se più di un processo scrive allo stesso tempo.\footnotemark\\ \macro{O\_NONBLOCK} & il file viene aperto in modalità non bloccante per - le operazioni di I/O: questo significa il fallimento di una \func{read} in - assenza di dati da leggere e quello di una \func{write} in caso di + le operazioni di I/O: questo significa il fallimento di \func{read} in + assenza di dati da leggere e quello di \func{write} in caso di impossibilità di scrivere immediatamente. L'opzione è effettiva solo per le fifo e per alcuni file di dispositivo. \\ \macro{O\_NDELAY} & in Linux\footnotemark\ è sinonimo di diff --git a/gapil.tex b/gapil.tex index f4a3dd3..06791aa 100644 --- a/gapil.tex +++ b/gapil.tex @@ -114,8 +114,8 @@ \include{filestd} \include{system} \include{signal} -\include{session} \include{fileadv} +\include{session} \include{ipc} \include{network} \include{socket} diff --git a/signal.tex b/signal.tex index 2f3b75b..b60b905 100644 --- a/signal.tex +++ b/signal.tex @@ -778,28 +778,29 @@ manipolatore; viene mantenuto invece ogni eventuale settaggio dell'azione a programmi eseguiti in background, che altrimenti sarebbero interrotti da una successiva pressione di \texttt{C-c} o \texttt{C-y}. -Per quanto riguarda tutte le altre system call esse vengono tradizionalmente -classificate, proprio in base al loro comportamento nei confronti dei segnali, -in \textsl{lente} (\textit{slow}) e \textsl{veloci} (\textit{fast}). La gran -parte appartiene a quest'ultima categoria che non è influenzata dall'arrivo di -un segnale. In tal caso un eventuale manipolatore viene sempre eseguito dopo -che la system call è stata completata. Esse sono dette \textsl{veloci} proprio -in quanto la loro esecuzione è sostanzialmente immediata e attendere per -eseguire un manipolatore non comporta nessun inconveniente. - -Esistono però dei casi in cui questo non è possibile perché renderebbe -impossibile una risposta pronta al segnale. In generale questo avviene tutte -le volte che si ha a che fare con system call che possono bloccarsi -indefinitamente, (quelle che, per questo, vengono chiamate \textsl{lente}). Un -elenco dei casi in cui si presenta questa situazione è il seguente: +Per quanto riguarda il comportamento di tutte le altre system call si danno +sostanzialmente due casi, a seconda che esse siano \textsl{lente} +(\textit{slow}) o \textsl{veloci} (\textit{fast}). La gran parte di esse +appartiene a quest'ultima categoria, che non è influenzata dall'arrivo di un +segnale. Esse sono dette \textsl{veloci} in quanto la loro esecuzione è +sostanzialmente immediata; la risposta al segnale viene sempre data dopo che +la system call è stata completata, in quanto attendere per eseguire un +manipolatore non comporta nessun inconveniente. + +In alcuni casi però alcune system call (che per questo motivo vengono chiamate +\textsl{lente}) possono bloccarsi indefinitamente. In questo caso non si può +attendere la conclusione della sistem call, perché questo renderebbe +impossibile una risposta pronta al segnale, per cui il manipolatore viene +eseguito prima che la system call sia ritornata. Un elenco dei casi in cui si +presenta questa situazione è il seguente: \begin{itemize} -\item lettura da file che possono bloccarsi in attesa di dati non ancora - presenti (come per certi file di dispositivo, la rete o le pipe). -\item scrittura sugli stessi file, nel caso in cui dati non possano essere +\item la lettura da file che possono bloccarsi in attesa di dati non ancora + presenti (come per certi file di dispositivo, i socket o le pipe). +\item la scrittura sugli stessi file, nel caso in cui dati non possano essere accettati immediatamente. -\item apertura di un file di dispositivo che richiede operazioni non immediate - per una una risposta. -\item operazioni eseguite con \func{ioctl} che non è detto possano essere +\item l'apertura di un file di dispositivo che richiede operazioni non + immediate per una una risposta. +\item le operazioni eseguite con \func{ioctl} che non è detto possano essere eseguite immediatamente. \item le funzioni di intercomunicazione che si bloccano in attesa di risposte da altri processi.