From: Simone Piccardi Date: Mon, 2 Dec 2002 23:06:59 +0000 (+0000) Subject: Aggiunte e correzioni alle funzioni per i file di lock X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=78a82bdb333ca71e395ba39a5c03745761341150;p=gapil.git Aggiunte e correzioni alle funzioni per i file di lock --- diff --git a/ipc.tex b/ipc.tex index ce4842e..7bf4186 100644 --- a/ipc.tex +++ b/ipc.tex @@ -2968,38 +2968,56 @@ il rilascio si pu solo se si opera all'interno di uno stesso filesystem.} L'uso di un file di lock presenta però parecchi problemi, che non lo rendono -una alternativa praticabile per la sincronizzazione:\footnote{ma può essere - una tecnica usata con successo quando l'esigenza è solo quella di segnalare - l'occupazione di una risorsa, senza necessità di attendere che questa si - liberi; ad esempio la si usa spesso per evitare interferenze sull'uso delle - porte seriali da parte di più programmi: qualora si trovi un file di lock il - programma che cerca di accedere alla seriale si limita a segnalare che la - risorsa non è disponibile.} anzitutto anche in questo caso in caso di -terminazione imprevista del processo lascia allocata la risorsa (il file di -lock) e questa deve essere sempre cancellata esplicitamente. Inoltre il -controllo della disponibilità può essere fatto solo con una tecnica di -\textit{polling}\index{polling}, che è molto inefficiente. - -Per questo motivo la tecnica alternativa più pulita è quella di fare ricorso -al \textit{file locking} trattato in \secref{sec:file_locking} ed utilizzare -\func{fcntl} su un file creato per l'occasione per ottenere un write lock. In -questo modo potremo usare il lock come un \textit{mutex}: per bloccare la -risorsa basterà acquisire il lock, per sbloccarla basterà rilasciare il lock; -una richiesta fatta con un write lock metterà automaticamente il processo in -stato di attesa, senza necessità di ricorrere al -\textit{polling}\index{polling} per determinare la disponibilità della -risorsa, e al rilascio della stessa da parte del processo che la occupava si -otterrà il nuovo lock atomicamente. +una alternativa praticabile per la sincronizzazione: anzitutto anche in questo +caso in caso di terminazione imprevista del processo lascia allocata la +risorsa (il file di lock) e questa deve essere sempre cancellata +esplicitamente. Inoltre il controllo della disponibilità può essere fatto +solo con una tecnica di \textit{polling}\index{polling}, che è molto +inefficiente. + +La tecnica può comunque essere usata con successo quando l'esigenza è solo +quella di segnalare l'occupazione di una risorsa, senza necessità di attendere +che questa si liberi; ad esempio la si usa spesso per evitare interferenze +sull'uso delle porte seriali da parte di più programmi: qualora si trovi un +file di lock il programma che cerca di accedere alla seriale si limita a +segnalare che la risorsa non è disponibile; sempre in \file{wrapper.h} si sono +predisposte due funzioni, \func{LockFile} e \func{UnlockFile}, da utilizzare +allo scopo. + +Dato che i file di lock presentano gli inconvenienti illustrati in precedenza, +la tecnica alternativa più comune è quella di fare ricorso al \textit{file + locking} (trattato in \secref{sec:file_locking}) usando \func{fcntl} su un +file creato per l'occasione per ottenere un write lock. In questo modo potremo +usare il lock come un \textit{mutex}: per bloccare la risorsa basterà +acquisire il lock, per sbloccarla basterà rilasciare il lock; una richiesta +fatta con un write lock metterà automaticamente il processo in stato di +attesa, senza necessità di ricorrere al \textit{polling}\index{polling} per +determinare la disponibilità della risorsa, e al rilascio della stessa da +parte del processo che la occupava si otterrà il nuovo lock atomicamente. Questo approccio presenta il notevole vantaggio che alla terminazione di un processo tutti i lock acquisiti vengono rilasciati automaticamente (alla -chiusura dei relativi file) e non ci si deve preoccupare di niente, e non -consuma risorse permanentemente allocate nel sistema, lo svantaggio è che +chiusura dei relativi file) e non ci si deve preoccupare di niente, inoltre +non consuma risorse permanentemente allocate nel sistema, lo svantaggio è che dovendo fare ricorso a delle operazioni sul filesystem esso è in genere leggermente più lento. -Il codice per implementare un mutex utilizzando il file locking è riportato in +\begin{figure}[!bht] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}{} + + \end{lstlisting} + \end{minipage} + \normalsize + \caption{Il codice delle funzioni che permettono di creare un + \textit{mutex} utilizzando il file locking.} + \label{fig:ipc_flock_mutex} +\end{figure} +Il codice per implementare un mutex utilizzando il file locking è riportato in +\figref{fig:ipc_flock_mutex}; come nel precedente caso dei mutex implementato +con i semafori le funzioni sono tre @@ -3012,7 +3030,7 @@ contenuto di un file nella memoria di un processo. Una della opzioni possibili utilizzabili con Linux è quella del \textit{memory mapping} anonimo\footnote{in altri sistemi una funzionalità simile a questa viene implementata mappando il file speciale \file{/dev/zero}.}, in tal caso -infatti +infatti \section{La comunicazione fra processi di POSIX} diff --git a/sources/wrappers.h b/sources/wrappers.h index 15ddd82..ed4a19b 100644 --- a/sources/wrappers.h +++ b/sources/wrappers.h @@ -5,7 +5,7 @@ * * Author: S. Piccardi * - * $Id: wrappers.h,v 1.4 2002/11/20 23:34:02 piccardi Exp $ + * $Id: wrappers.h,v 1.5 2002/12/02 23:06:59 piccardi Exp $ * ***************************************************************/ #include /* IPC semaphore declarations */ @@ -161,24 +161,18 @@ inline char * ShmFind(key_t ipc_key, int shm_size) return shptr; } /* - * Function LockFile: - * Create a lockfile of the given pathname. + * Function LockFile & UnlockFile: + * Create and remove a lockfile of the given pathname. * Fail and exit in case of error or existence of the same lock * file, using unlink do not need to remove the file, */ -inline void LockFile(const char* path_name) +inline int LockFile(const char* path_name) { - if (open(path_name, O_EXCL|O_CREAT)<0) { - perror("Already active"); - exit(1); - } + return open(path_name, O_EXCL|O_CREAT); } -inline void UnlockFile(const char* path_name) +inline int UnlockFile(const char* path_name) { - if (unlink(path_name)) { - perror("error, cannot unlink"); - exit(1); - } + return unlink(path_name); } /* * Function Signal