From: Simone Piccardi Date: Mon, 12 Nov 2001 18:38:32 +0000 (+0000) Subject: Correzioni ulteriori, segnalate da Vosti. X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=132101028053d47151d1957b925fc5a7631c01e6;hp=b6d559b9429afcc0d64137913e8f16d49857a6c9 Correzioni ulteriori, segnalate da Vosti. --- diff --git a/fileadv.tex b/fileadv.tex index 222fcae..9d084a8 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -1,5 +1,5 @@ \chapter{I/O avanzato} -\label{sec:file_advanced} +\label{cha:file_advanced} diff --git a/filedir.tex b/filedir.tex index be2d5c6..04c30b3 100644 --- a/filedir.tex +++ b/filedir.tex @@ -142,9 +142,9 @@ restrizioni Una delle caratteristiche di queste funzioni è che la creazione/rimozione della nome dalla directory e l'incremento/decremento del numero di riferimenti -nell'inode deve essere una operazione atomica (cioè non interrompibile da -altri processi), per questo entrambe queste funzioni sono realizzate tramite -una singola system call. +nell'inode deve essere una operazione atomica (si veda +\secref{cha:proc_atom_oper}), per questo entrambe queste funzioni sono +realizzate tramite una singola system call. Si ricordi infine che il file non viene eliminato dal disco fintanto che tutti i riferimenti ad esso sono stati cancellati, solo quando il \textit{link diff --git a/fileunix.tex b/fileunix.tex index 7ae7ce6..3001194 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -297,16 +297,16 @@ cio \footnotetext[3]{Denial of Service, si chiamano così attacchi miranti ad impedire un servizio causando una qualche forma di carico eccessivo per il - sistema, che resta bloccato nelle risposte all'attacco} + sistema, che resta bloccato nelle risposte all'attacco.} \footnotetext[4]{il problema è che NFS non supporta la scrittura in append, ed il kernel deve simularla, ma questo comporta la possibilità di una race - condition} + condition, vedi \secref{sec:file_atomic}.} \footnotetext[5]{l'opzione origina da SVr4, dove però causava il ritorno da una \func{read} con un valore nullo e non con un errore, questo introduce una ambiguità, dato che come vedremo in \secref{sec:file_read} il ritorno di - zero da parte di \func{read} ha il significato di una end-of-file} + zero da parte di \func{read} ha il significato di una end-of-file.} Il nuovo file descriptor non è condiviso con nessun altro processo, (torneremo @@ -465,9 +465,8 @@ Si tenga presente inoltre che usare \macro{SEEK\_END} non assicura affatto che successiva scrittura avvenga alla fine del file, infatti se questo è stato aperto anche da un altro processo che vi ha scritto, la fine del file può essersi spostata, ma noi scriveremo alla posizione settata in precedenza. -Questa è una potenziale sorgente di \textit{race condition}, e quando si vuole -essere sicuri di scrivere alla fine del file questo deve essere posto in -modalità \macro{O\_APPEND}. +(questa è una potenziale sorgente di \textit{race condition}, vedi +\secref{sec:file_atomic}). Non tutti i file supportano la capacità di eseguire una \func{lseek}, in questo caso la funzione ritorna l'errore \macro{EPIPE}. Questo, oltre che per @@ -726,11 +725,43 @@ vengono toccati anche in caso di condivisione della voce della \textit{file Come si è visto in un sistema unix è sempre possibile per più processi accedere in contemporanea allo stesso file, e che le operazioni di lettura e -scrittura saranno fatte in base alla posizione corrente nel file. Ovviamente -senza prevedere opportuni meccanismi di sincronizzazione le operazioni -potranno mescolarsi in maniera imprevedibile. L'unica garanzia è che se si è -in modalità \macro{O\_APPEND} il sistema assicura che si scriva (con il -procedimento appena esposto) sempre alla fine del file. +scrittura possono essere fatte da ogni processo in maniera autonoma in base +ad una posizione corrente nel file che è locale a ciascuno di essi. + +Se dal punto di vista della lettura dei dati questo non comporta nessun +problema, quando si andrà a scrivere le operazioni potranno mescolarsi in +maniera imprevedibile. Il sistema però fornisce in alcuni casi la possibilità +di eseguire alcune operazioni di scrittura in maniera coordinata anche senza +utilizzare meccanismi di sincronizzazione più complessi (come il \textit{file + locking}, che esamineremo in \secref{cha:file_advanced}). + +Un caso tipico di necessità di accesso condiviso in scrittura è quello in cui +vari processi devono scrivere alla fine di un file (ad esempio un file di +log). Come accennato in \secref{sec:file_lseek} settare la posizione alla fine +del file e poi scrivere può condurre ad una \textit{race condition}: infatti +può succedere che un secondo processo scriva alla fine del file fra la +\func{lseek} e la \func{write}; in questo caso, come abbiamo appena visto, il +file sarà esteso, ma il nostro primo processo avrà ancora la posizione +corrente settata con la \func{lseek} che non corrisponde più alla fine del +file, e la successiva \func{write} sovrascriverà i dati del secondo processo. + +Il problema è che usare due system call in successione non è una operazione +atomica; il problema è stato risolto introducendo la modalità +\macro{O\_APPEND}, in questo caso infatti, come abbiamo visto, è il kernel che +aggiorna automaticamente la posizione alla fine del file prima di effettuare +la scrittura, e poi estende il file. Tutto questo avviene all'interno di una +singola system call (la \func{write}) che non essendo interrompibile da un +altro processo costituisce una operazione atomica. + +Un altro caso tipico in cui è necessaria l'atomicità è quello in cui si vuole +creare un file di lock, bloccandosi se il file esiste. In questo caso la +sequenza logica porterebbe a verificare prima l'esistenza del file con una +\func{stat} per poi crearlo con una \func{creat}; di nuovo avremmo la +possibilità di una race condition da parte di un altro processo che crea lo +stesso file fra il controllo e la creazione. + +Per questo motivo sono stati introdotti i flag \macro{O\_CREAT} +\macro{O\_EXCL} diff --git a/prochand.tex b/prochand.tex index f5decd7..2316a5b 100644 --- a/prochand.tex +++ b/prochand.tex @@ -1690,11 +1690,11 @@ non possono essere interrotte (o subire interferenze pericolose) da altri processi. Nel caso dei segnali invece la situazione è molto più delicata, in quanto lo -stesso processo può essere interrotto in qualunque momento, e le operazioni di -un eventuale \textit{signal handler} saranno compiute nello stesso spazio di -indirizzi. Per questo anche solo il solo accesso o l'assegnazione di una -variabile possono non essere più operazioni atomiche (torneremo su questi -aspetti in \secref{sec:sign_xxx}). +stesso processo, e pure alcune system call, possono essere interrotti in +qualunque momento, e le operazioni di un eventuale \textit{signal handler} +sono compiute nello stesso spazio di indirizzi del processo. Per questo anche +solo il solo accesso o l'assegnazione di una variabile possono non essere più +operazioni atomiche (torneremo su questi aspetti in \secref{sec:sign_xxx}). In questo caso il sistema provvede un tipo di dato, il \type{sig\_atomic\_t}, il cui accesso è assicurato essere atomico. In pratica comunque si può @@ -1728,9 +1728,9 @@ condivise siano opportunamente protette da meccanismi di sincronizzazione Un caso particolare di \textit{race condition} sono poi i cosiddetti \textit{deadlock}; l'esempio tipico è quello di un flag di ``occupazione'' che viene rilasciato da un evento asincrono fra il controllo (in cui viene trovato -occupato) e la successiva messa in attesa, attesa che a questo punto diventerà +occupato) e la successiva messa in attesa, che a questo punto diventerà perpetua (da cui il nome di \textit{deadlock}) in quanto l'evento di sblocco -di questa è stato perso. +del flag è stato perso fra il controllo e la messa in attesa. \subsection{Le funzioni rientranti}