+In caso di successo la funzione aggiorna anche i seguenti campi di
+\var{shmid\_ds}:
+\begin{itemize*}
+\item il tempo \var{shm\_dtime} dell'ultima operazione di sganciamento viene
+ impostato al tempo corrente.
+\item il \acr{pid} \var{shm\_lpid} dell'ultimo processo che ha operato sul
+ segmento viene impostato a quello del processo corrente.
+\item il numero \var{shm\_nattch} di processi agganciati al segmento viene
+ decrementato di uno.
+\end{itemize*}
+inoltre la regione di indirizzi usata per il segmento di memoria condivisa
+viene tolta dallo spazio di indirizzi del processo.
+
+Benché la memoria condivisa costituisca il meccanismo di intercomunicazione
+fra processi più veloce, essa non è sempre il più appropriato, dato che, come
+abbiamo visto, si avrà comunque la necessità di una sincronizzazione degli
+accessi. Per questo motivo, quando la comunicazione fra processi è
+sequenziale, altri meccanismi come le pipe, le fifo o i socket, che non
+necessitano di sincronizzazione esplicita, sono da preferire. Essa diventa
+l'unico meccanismo possibile quando la comunicazione non è
+sequenziale\footnote{come accennato in \secref{sec:ipc_sysv_mq} per la
+ comunicazione non sequenziale si possono usare le code di messaggi,
+ attraverso l'uso del campo \var{mtype}, ma solo se quest'ultima può essere
+ effettuata in forma di messaggio.} o quando non può avvenire secondo una
+modalità predefinita.
+
+Un esempio classico di uso della memoria condivisa è quello del ``monitor'',
+in cui essa viene per scambiare informazioni fra un processo ``server'' che vi
+scrive dei dati di interesse generale che ha ottenuto, e tutti i processi
+``client'' interessati agli stessi dati che così possono leggerli in maniera
+completamente asincrona. Con questo schema di funzionamento da una parte si
+evita che ciascun processo ``client'' debbia compiere l'operazione,
+potenzialmente onerosa, di ricavare e trattare i dati, e dall'altra si evita
+al processo ``server'' di dover gestire l'invio a tutti i client di tutti i
+dati (non potendo il server sapere quali di essi servono effettivamente al
+singolo client).
+
+Nel nostro caso implementeremo un ``monitor'' di una directory: un processo si
+incaricherà di tenere sotto controllo alcuni parametri relativi ad una
+directory (il numero dei file contenuti, la dimenzione totale, ecc.) che
+saranno salvati in un segmento di memoria condivisa cui altri processi
+potranno accedere per ricavare la parte di informazione che interessa.
+
+
+
+
+%% Per capire meglio il funzionamento delle funzioni facciamo ancora una volta
+%% riferimento alle strutture con cui il kernel implementa i segmenti di memoria
+%% condivisa; uno schema semplificato della struttura è illustrato in
+%% \figref{fig:ipc_shm_struct}.
+
+%% \begin{figure}[htb]
+%% \centering
+%% \includegraphics[width=10cm]{img/shmstruct}
+%% \caption{Schema dell'implementazione dei segmenti di memoria condivisa in
+%% Linux.}
+%% \label{fig:ipc_shm_struct}
+%% \end{figure}
+
+
+
+
+\section{Tecniche alternative}
+\label{sec:ipc_alternatives}
+
+Come abbiamo detto in \secref{sec:ipc_sysv_generic}, e ripreso nella
+descrizione dei singoli oggetti che ne fan parte, il \textit{SysV IPC}
+presenta numerosi problemi; in \cite{APUE}\footnote{in particolare nel
+ capitolo 14.} Stevens ne effettua una accurata analisi (alcuni dei
+concetti sono già stati accennati in precedenza) ed elenca alcune possibili
+tecniche alternative, che vogliamo riprendere in questa sezione.
+
+
+\subsection{Alternative alle code di messaggi}
+\label{sec:ipc_mq_alternative}
+
+Le code di messaggi sono probabilmente il meno usato degli oggetti del
+\textit{SysV IPC}; esse infatti nacquero principalmente come meccanismo di
+comunicazione bidirezionale quando ancora le pipe erano unidirezionali; con la
+disponibilità di \func{socketpair} (vedi \secref{sec:ipc_socketpair}) o
+utilizzando una coppia di pipe, si può ottenere questo risultato senza
+incorrere nelle complicazioni introdotte dal \textit{SysV IPC}.
+
+In realtà, grazie alla presenza del campo \var{mtype}, le code di messaggi
+hanno delle caratteristiche ulteriori, consentendo una classificazione dei
+messaggi ed un accesso non rigidamente sequenziale; due caratteristiche che
+sono impossibili da ottenere con le pipe e i socket\index{socket} di
+\func{socketpair}. A queste esigenze però si può comunque ovviare in maniera
+diversa con un uso combinato della memoria condivisa e dei meccanismi di
+sincronizzazione, per cui alla fine l'uso delle code di messaggi classiche è
+relativamente poco diffuso.
+
+
+
+\subsection{I \textsl{file di lock}}
+\label{sec:ipc_file_lock}
+
+\index{file!di lock|(}
+Come illustrato in \secref{sec:ipc_sysv_sem} i semafori del \textit{SysV IPC}
+presentano una interfaccia inutilmente complessa e con alcuni difetti
+strutturali, per questo quando si ha una semplice esigenza di sincronizzazione
+per la quale basterebbe un semaforo binario (quello che abbiamo definito come
+\textit{mutex}), per indicare la disponibilità o meno di una risorsa, senza la
+necessità di un contatore come i semafori, si possono utilizzare metodi
+alternativi.
+
+La prima possibilità, utilizzata fin dalle origini di Unix, è quella di usare
+dei \textsl{file di lock} (per i quali esiste anche una opportuna directory,
+\file{/var/lock}, nel filesystem standard). Per questo si usa la
+caratteristica della funzione \func{open} (illustrata in
+\secref{sec:file_open}) che prevede\footnote{questo è quanto dettato dallo
+ standard POSIX.1, ciò non toglie che in alcune implementazioni questa
+ tecnica possa non funzionare; in particolare per Linux, nel caso di NFS, si
+ è comunque soggetti alla possibilità di una race condition.} che essa
+ritorni un errore quando usata con i flag di \const{O\_CREAT} e
+\const{O\_EXCL}. In tal modo la creazione di un \textsl{file di lock} può
+essere eseguita atomicamente, il processo che crea il file con successo si può
+considerare come titolare del lock (e della risorsa ad esso associata) mentre
+il rilascio si può eseguire con una chiamata ad \func{unlink}.
+
+Un esempio dell'uso di questa funzione è mostrato dalle funzioni
+\func{LockFile} ed \func{UnlockFile} riportate in \figref{fig:ipc_file_lock}
+(sono contenute in \file{LockFile.c}, un'altro dei sorgenti allegati alla
+guida) che permettono rispettivamente di creare e rimuovere un \textsl{file di
+ lock}. Come si può notare entrambe le funzioni sono elementari; la prima
+(\texttt{\small 4--10}) si limita ad aprire il file di lock (\texttt{\small
+ 9}) nella modalità descritta, mentre la seconda (\texttt{\small 11--17}) lo
+cancella con \func{unlink}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}{}
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h> /* unix standard functions */
+/*
+ * Function LockFile:
+ */
+int LockFile(const char* path_name)
+{
+ return open(path_name, O_EXCL|O_CREAT);
+}
+/*
+ * Function UnlockFile:
+ */
+int UnlockFile(const char* path_name)
+{
+ return unlink(path_name);
+}
+
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{Il codice delle funzioni \func{LockFile} e \func{UnlockFile} che
+ permettono di creare e rimuovere un \textsl{file di lock}.}
+ \label{fig:ipc_file_lock}
+\end{figure}