+Uno dei limiti di questa tecnica è che, come abbiamo già accennato in
+\secref{sec:file_open}, questo comportamento di \func{open} può non funzionare
+(la funzione viene eseguita, ma non è garantita l'atomicità dell'operazione)
+se il filesystem su cui si va ad operare è su NFS; in tal caso si può adottare
+una tecnica alternativa che prevede l'uso della \func{link} per creare come
+\textsl{file di lock} un hard link ad un file esistente; se il link esiste già
+e la funzione fallisce, significa che la risorsa è bloccata e potrà essere
+sbloccata solo con un \func{unlink}, altrimenti il link è creato ed il lock
+acquisito; il controllo e l'eventuale acquisizione sono atomici; la soluzione
+funziona anche su NFS, ma ha un'altro difetto è che è quello di poterla usare
+solo se si opera all'interno di uno stesso filesystem.
+
+Un generale comunque l'uso di un \textsl{file di lock} presenta parecchi
+problemi, che non lo rendono una alternativa praticabile per la
+sincronizzazione: anzitutto anche in questo caso, in caso di terminazione
+imprevista del processo, si lascia allocata la risorsa (il \textsl{file di
+ lock}) e questa deve essere sempre cancellata esplicitamente. Inoltre il
+controllo della disponibilità può essere eseguito solo con una tecnica di
+\textit{polling}\index{polling}, ed è quindi molto inefficiente.
+
+La tecnica dei file di lock non di meno ha una sua utilità, e può 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.\index{file!di lock|)}
+
+\subsection{La sincronizzazione con il \textit{file locking}}
+\label{sec:ipc_lock_file}
+
+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}\index{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, 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.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}{}
+/*
+ * Function LockMutex: lock a file (creating it if not existent).
+ */
+int LockMutex(const char *path_name)
+{
+ int fd, res;
+ struct flock lock; /* file lock structure */
+ /* first open the file (creating it if not existent) */
+ if ( (fd = open(path_name, O_EXCL|O_CREAT)) < 0) { /* first open file */
+ return fd;
+ }
+ /* set flock structure */
+ lock.l_type = F_WRLCK; /* set type: read or write */
+ lock.l_whence = SEEK_SET; /* start from the beginning of the file */
+ lock.l_start = 0; /* set the start of the locked region */
+ lock.l_len = 0; /* set the length of the locked region */
+ /* do locking */
+ if ( (res = fcntl(fd, F_SETLKW, &lock)) < 0 ) {
+ return res;
+ }
+ return 0;
+}
+/*
+ * Function UnLockMutex: unlock a file.
+ */
+int UnlockMutex(const char *path_name)
+{
+ int fd, res;
+ struct flock lock; /* file lock structure */
+ /* first open the file */
+ if ( (fd = open(path_name, O_RDWR)) < 0) { /* first open file */
+ return fd;
+ }
+ /* set flock structure */
+ lock.l_type = F_UNLCK; /* set type: unlock */
+ lock.l_whence = SEEK_SET; /* start from the beginning of the file */
+ lock.l_start = 0; /* set the start of the locked region */
+ lock.l_len = 0; /* set the length of the locked region */
+ /* do locking */
+ if ( (res = fcntl(fd, F_SETLK, &lock)) < 0 ) {
+ return res;
+ }
+ return 0;
+}
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{Il codice delle funzioni che permettono di creare un
+ \textit{mutex} utilizzando il file locking\index{file!locking}.}
+ \label{fig:ipc_flock_mutex}
+\end{figure}
+
+Il codice per implementare un mutex utilizzando il file
+locking\index{file!locking} è riportato in \figref{fig:ipc_flock_mutex}; a
+differenza del precedente caso in cui si sono usati i semafori le funzioni
+questa volta sono sufficienti due funzioni, \func{LockMutex} e
+\func{UnlockMutex}, usate rispettivamente per acquisire e rilasciare il mutex.
+
+La prima funzione (\texttt{\small 1--22}) serve per acquisire il mutex.
+Anzitutto si apre (\texttt{\small 9--11}), creandolo se non esiste, il file
+specificato dall'argomento \param{pathname}. In caso di errore si ritorna
+immediatamente, altrimenti si prosegue impostando (\texttt{\small 12--16}) la
+struttura \var{lock} in modo da poter acquisire un write lock sul file.
+Infine si richiede (\texttt{\small 17--20}) il file lock (restituendo il
+codice di ritorno di \func{fcntl} caso di errore). Se il file è libero il lock
+è acquisito e la funzione ritorna immediatamente; altrimenti \func{fcntl} si
+bloccherà (si noti che la si è chiamata con \func{F\_SETLKW}) fino al rilascio
+del lock.
+
+La seconda funzione (\texttt{\small 23--44}) serve a rilasciare il mutex. Di
+nuovo si apre (\texttt{\small 30--33}) il file specificato dall'argomento
+\param{pathname} (che stavolta deve esistere), ritornando immediatamente in
+caso di errore. Poi si passa ad inizializzare (\texttt{\small 34--38}) la
+struttura \var{lock} per il rilascio del lock, che viene effettuato
+(\texttt{\small 39--42}) subito dopo.
+
+ \subsection{Il \textit{memory mapping} anonimo}
+\label{sec:ipc_mmap_anonymous}
+
+Abbiamo già visto che quando i processi sono \textsl{correlati}\footnote{se
+ cioè hanno almeno un progenitore comune.} l'uso delle pipe può costituire
+una valida alternativa alle code di messaggi; nella stessa situazione si può
+evitare l'uso di una memoria condivisa facendo ricorso al cosiddetto
+\textit{memory mapping} anonimo.
+
+Abbiamo visto in \secref{sec:file_memory_map} che è possibile mappare il
+contenuto di un file nella memoria di un processo, e che, quando viene usato
+il flag \const{MAP\_SHARED}, le modifiche effettuate al contenuto del file
+vengono viste da tutti i processi che lo hanno mappato. Utilizzare questa
+tecnica per creare una memoria condivisa fra processi diversi è estremamente
+inefficiente, in quanto occorre passare attraverso il disco. Però abbiamo
+visto anche che se si esegue la mappatura con il flag \const{MAP\_ANONYMOUS}
+la regione mappata non viene associata a nessun file, anche se quanto scritto
+rimane in memoria e può essere riletto; allora, dato che un processo figlio
+mantiene nel suo spazio degli indirizzi anche le regioni mappate, esso sarà
+anche in grado di accedere a quanto in esse è contenuto.
+
+In questo modo diventa possibile creare una memoria condivisa fra processi
+diversi, purché questi abbiano almeno un progenitore comune che ha effettuato
+il \textit{memory mapping} anonimo.\footnote{nei sistemi derivati da SysV una
+ funzionalità simile a questa viene implementata mappando il file speciale
+ \file{/dev/zero}. In tal caso i valori scritti nella regione mappata non
+ vengono ignorati (come accade qualora si scriva direttamente sul file), ma
+ restano in memoria e possono essere riletti secondo le stesse modalità usate
+ nel \textit{memory mapping} anonimo.} Un esempio di utilizzo di questa
+tecnica è mostrato in