+Come esempio di uso dell'interfaccia dei semafori vediamo come implementare
+con essa dei semplici \textit{mutex} (cioè semafori binari), tutto il codice
+in questione, contenuto nel file \file{Mutex.c} allegato ai sorgenti, è
+riportato in \figref{fig:ipc_mutex_create}. Utilizzeremo l'interfaccia per
+creare un insieme contenente un singolo semaforo, per il quale poi useremo un
+valore unitario per segnalare la disponibilità della risorsa, ed un valore
+nullo per segnalarne l'indisponibilità.
+
+\begin{figure}[!bht]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}{}
+/* Function MutexCreate: create a mutex/semaphore */
+int MutexCreate(key_t ipc_key)
+{
+ const union semun semunion={1}; /* semaphore union structure */
+ int sem_id, ret;
+ sem_id = semget(ipc_key, 1, IPC_CREAT|0666); /* get semaphore ID */
+ if (sem_id == -1) { /* if error return code */
+ return sem_id;
+ }
+ ret = semctl(sem_id, 0, SETVAL, semunion); /* init semaphore */
+ if (ret == -1) {
+ return ret;
+ }
+ return sem_id;
+}
+/* Function MutexFind: get the semaphore/mutex Id given the IPC key value */
+int MutexFind(key_t ipc_key)
+{
+ return semget(ipc_key,1,0);
+}
+/* Function MutexRead: read the current value of the mutex/semaphore */
+int MutexRead(int sem_id)
+{
+ return semctl(sem_id, 0, GETVAL);
+}
+/* Define sembuf structures to lock and unlock the semaphore */
+struct sembuf sem_lock={ /* to lock semaphore */
+ 0, /* semaphore number (only one so 0) */
+ -1, /* operation (-1 to use resource) */
+ SEM_UNDO}; /* flag (set for undo at exit) */
+struct sembuf sem_ulock={ /* to unlock semaphore */
+ 0, /* semaphore number (only one so 0) */
+ 1, /* operation (1 to release resource) */
+ SEM_UNDO}; /* flag (in this case 0) */
+/* Function MutexLock: to lock a mutex/semaphore */
+int MutexLock(int sem_id)
+{
+ return semop(sem_id, &sem_lock, 1);
+}
+/* Function MutexUnlock: to unlock a mutex/semaphore */
+int MutexUnlock(int sem_id)
+{
+ return semop(sem_id, &sem_ulock, 1);
+}
+/* Function MutexRemove: remove a mutex/semaphore */
+int MutexRemove(int sem_id)
+{
+ return semctl(sem_id, 0, IPC_RMID);
+}
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{Il codice delle funzioni che permettono di creare o recuperare
+ l'identificatore di un semaforo da utilizzare come \textit{mutex}.}
+ \label{fig:ipc_mutex_create}
+\end{figure}
+
+La prima funzione (\texttt{\small 2--15}) è \func{MutexCreate} che data una
+chiave crea il semaforo usato per il mutex e lo inizializza, restituendone
+l'identificatore. Il primo passo (\texttt{\small 6}) è chiamare \func{semget}
+con \const{IPC\_CREATE} per creare il semaforo qualora non esista,
+assegnandogli i privilegi di lettura e scrittura per tutti. In caso di errore
+(\texttt{\small 7--9}) si ritorna subito il risultato di \func{semget},
+altrimenti (\texttt{\small 10}) si inizializza il semaforo chiamando
+\func{semctl} con il comando \const{SETVAL}, utilizzando l'unione
+\struct{semunion} dichiarata ed avvalorata in precedenza (\texttt{\small 4})
+ad 1 per significare che risorsa è libera. In caso di errore (\texttt{\small
+ 11--13}) si restituisce il valore di ritorno di \func{semctl}, altrimenti
+(\texttt{\small 14}) si ritorna l'identificatore del semaforo.
+
+La seconda funzione (\texttt{\small 17--20}) è \func{MutexFind}, che, data una
+chiave, restituisce l'identificatore del semaforo ad essa associato. La
+comprensione del suo funzionamento è immediata in quanto essa è soltanto un
+\textit{wrapper}\footnote{si chiama così una funzione usata per fare da
+ \textsl{involucro} alla chiamata di un altra, usata in genere per
+ semplificare un'interfaccia (come in questo caso) o per utilizzare con la
+ stessa funzione diversi substrati (librerie, ecc.) che possono fornire le
+ stesse funzionalità.} di una chiamata a \func{semget} per cercare
+l'identificatore associato alla chiave, il valore di ritorno di quest'ultima
+viene passato all'indietro al chiamante.
+
+La terza funzione (\texttt{\small 22--25}) è \func{MutexRead} che, dato un
+identificatore, restituisce il valore del semaforo associato al mutex. Anche
+in questo caso la funzione è un \textit{wrapper} per una chiamata a
+\func{semctl} con il comando \const{GETVAL}, che permette di restituire il
+valore del semaforo.
+
+La quarta e la quinta funzione (\texttt{\small 36--44}) sono \func{MutexLock},
+e \func{MutexUnlock}, che permettono rispettivamente di bloccare e sbloccare
+il mutex. Entrambe fanno da wrapper per \func{semop}, utilizzando le due
+strutture \var{sem\_lock} e \var{sem\_unlock} definite in precedenza
+(\texttt{\small 27--34}). Si noti come per queste ultime si sia fatto uso
+dell'opzione \const{SEM\_UNDO} per evitare che il semaforo resti bloccato in
+caso di terminazione imprevista del processo.
+
+L'ultima funzione (\texttt{\small 46--49}) della serie, è \func{MutexRemove},
+che rimuove il mutex. Anche in questo caso si ha un wrapper per una chiamata a
+\func{semctl} con il comando \const{IPC\_RMID}, che permette di cancellare il
+smemaforo; il valore di ritorno di quest'ultima viene passato all'indietro.
+
+Chiamare \func{MutexLock} decrementa il valore del semaforo: se questo è
+libero (ha già valore 1) sarà bloccato (valore nullo), se è bloccato la
+chiamata a \func{semop} si bloccherà fintanto che la risorsa non venga
+rilasciata. Chiamando \func{MutexUnlock} il valore del semaforo sarà
+incrementato di uno, sbloccandolo qualora fosse bloccato. Si noti che occorre
+eseguire sempre prima \func{MutexLock} e poi \func{MutexUnlock}, perché se per
+un qualche errore si esegue più volte quest'ultima il valore del semaforo
+crescerebbe oltre 1, e \func{MutexLock} non avrebbe più l'effetto aspettato
+(bloccare la risorsa quando questa è considerata libera). Si tenga presente
+che usare \func{MutexRead} per controllare il valore dei mutex prima di
+proseguire non servirebbe comunque, dato che l'operazione non sarebbe atomica.
+Vedremo in \secref{sec:ipc_lock_file} come sia possibile ottenere
+un'interfaccia analoga a quella appena illustrata, senza incorrere in questi
+problemi, usando il file locking\index{file!locking}.
+
+