+
+\subsection{Semafori}
+\label{sec:ipc_posix_sem}
+
+Fino alla serie 2.4.x del kernel esisteva solo una implementazione parziale
+dei semafori POSIX che li realizzava solo a livello di \textit{thread} e non
+di processi,\footnote{questo significava che i semafori erano visibili solo
+ all'interno dei \textit{thread} creati da un singolo processo, e non
+ potevano essere usati come meccanismo di sincronizzazione fra processi
+ diversi.} fornita attraverso la sezione delle estensioni \textit{real-time}
+della \acr{glibc} (quelle che si accedono collegandosi alla libreria
+\texttt{librt}). Esisteva inoltre una libreria che realizzava (parzialmente)
+l'interfaccia POSIX usando le funzioni dei semafori di \textit{SysV-IPC}
+(mantenendo così tutti i problemi sottolineati in
+sez.~\ref{sec:ipc_sysv_sem}).
+
+A partire dal kernel 2.5.7 è stato introdotto un meccanismo di
+sincronizzazione completamente nuovo, basato sui cosiddetti \textit{futex} (la
+sigla sta per \textit{fast user mode mutex}) con il quale è stato possibile
+implementare una versione nativa dei semafori POSIX. Grazie a questo con i
+kernel della serie 2.6 e le nuove versioni della \acr{glibc} che usano questa
+nuova infrastruttura per quella che viene chiamata \textit{New Posix Thread
+ Library}, sono state implementate anche tutte le funzioni dell'interfaccia
+dei semafori POSIX.
+
+Anche in questo caso è necessario appoggiarsi alla libreria per le estensioni
+\textit{real-time} \texttt{librt}, questo significa che se si vuole utilizzare
+questa interfaccia, oltre ad utilizzare gli opportuni file di definizione,
+occorrerà compilare i programmi con l'opzione \texttt{-lrt} o con
+\texttt{-lpthread} se si usano questi ultimi.
+
+La funzione che permette di creare un nuovo semaforo POSIX, creando il
+relativo file, o di accedere ad uno esistente, è \funcd{sem\_open}, questa
+prevede due forme diverse a seconda che sia utilizzata per aprire un semaforo
+esistente o per crearne uno nuovi, i relativi prototipi sono:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fhead{sys/stat.h}
+\fhead{fcntl.h}
+\fdecl{sem\_t *sem\_open(const char *name, int oflag)}
+\fdecl{sem\_t *sem\_open(const char *name, int oflag, mode\_t mode,
+ unsigned int value)}
+
+\fdesc{Crea un semaforo o ne apre uno esistente.}
+}
+{La funzione ritorna l'indirizzo del semaforo in caso di successo e
+ \constd{SEM\_FAILED} per un errore, nel qual caso \var{errno} assumerà uno
+ dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] il semaforo esiste ma non si hanno permessi
+ sufficienti per accedervi.
+ \item[\errcode{EEXIST}] si sono specificati \const{O\_CREAT} e
+ \const{O\_EXCL} ma il semaforo esiste.
+ \item[\errcode{EINVAL}] il valore di \param{value} eccede
+ \constd{SEM\_VALUE\_MAX} o il nome è solo ``\texttt{/}''.
+ \item[\errcode{ENAMETOOLONG}] si è utilizzato un nome troppo lungo.
+ \item[\errcode{ENOENT}] non si è usato \const{O\_CREAT} ed il nome
+ specificato non esiste.
+ \end{errlist}
+ ed inoltre \errval{EMFILE}, \errval{ENFILE} ed \errval{ENOMEM} nel loro
+ significato generico.
+
+}
+\end{funcproto}
+
+L'argomento \param{name} definisce il nome del semaforo che si vuole
+utilizzare, ed è quello che permette a processi diversi di accedere allo
+stesso semaforo. Questo deve essere specificato nella stessa forma utilizzata
+per i segmenti di memoria condivisa, con un nome che inizia con ``\texttt{/}''
+e senza ulteriori ``\texttt{/}'', vale a dire nella forma
+\texttt{/nome-semaforo}.
+
+Con Linux i file associati ai semafori sono mantenuti nel filesystem virtuale
+\texttt{/dev/shm}, e gli viene assegnato automaticamente un nome nella forma
+\texttt{sem.nome-semaforo}, si ha cioè una corrispondenza per cui
+\texttt{/nome-semaforo} viene rimappato, nella creazione tramite
+\func{sem\_open}, su \texttt{/dev/shm/sem.nome-semaforo}. Per questo motivo la
+dimensione massima per il nome di un semaforo, a differenza di quanto avviene
+per i segmenti di memoria condivisa, è pari a \const{NAME\_MAX}$ - 4$.
+
+L'argomento \param{oflag} è quello che controlla le modalità con cui opera la
+funzione, ed è passato come maschera binaria; i bit corrispondono a quelli
+utilizzati per l'analogo argomento di \func{open}, anche se dei possibili
+valori visti in sez.~\ref{sec:file_open_close} sono utilizzati soltanto
+\const{O\_CREAT} e \const{O\_EXCL}.
+
+Se si usa \const{O\_CREAT} si richiede la creazione del semaforo qualora
+questo non esista, ed in tal caso occorre utilizzare la seconda forma della
+funzione, in cui si devono specificare sia un valore iniziale con l'argomento
+\param{value},\footnote{e si noti come così diventa possibile, differenza di
+ quanto avviene per i semafori del \textit{SysV-IPC}, effettuare in maniera
+ atomica creazione ed inizializzazione di un semaforo usando una unica
+ funzione.} che una maschera dei permessi con l'argomento
+\param{mode}; se il semaforo esiste già questi saranno semplicemente
+ignorati. Usando il flag \const{O\_EXCL} si richiede invece la verifica che il
+semaforo non esista, ed usandolo insieme ad \const{O\_CREAT} la funzione
+fallisce qualora un semaforo con lo stesso nome sia già presente.
+
+Si tenga presente che, come accennato in sez.~\ref{sec:ipc_posix_generic}, i
+semafori usano la semantica standard dei file per quanto riguarda i controlli
+di accesso, questo significa che un nuovo semaforo viene sempre creato con
+l'\ids{UID} ed il \ids{GID} effettivo del processo chiamante, e che i permessi
+indicati con \param{mode} vengono filtrati dal valore della \textit{umask} del
+processo. Inoltre per poter aprire un semaforo è necessario avere su di esso
+sia il permesso di lettura che quello di scrittura.
+
+La funzione restituisce in caso di successo un puntatore all'indirizzo del
+semaforo con un valore di tipo \ctyp{sem\_t *}, è questo valore che dovrà
+essere passato alle altre funzioni per operare sul semaforo stesso, e non sarà
+più necessario fare riferimento al nome, che potrebbe anche essere rimosso con
+\func{sem\_unlink}.
+
+Una volta che si sia ottenuto l'indirizzo di un semaforo, sarà possibile
+utilizzarlo; se si ricorda quanto detto all'inizio di
+sez.~\ref{sec:ipc_sysv_sem}, dove si sono introdotti i concetti generali
+relativi ai semafori, le operazioni principali sono due, quella che richiede
+l'uso di una risorsa bloccando il semaforo e quella che rilascia la risorsa
+liberando il semaforo. La prima operazione è effettuata dalla funzione
+\funcd{sem\_wait}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_wait(sem\_t *sem)}
+
+\fdesc{Blocca un semaforo.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+ \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione cerca di decrementare il valore del semaforo indicato dal
+puntatore \param{sem}, se questo ha un valore positivo, cosa che significa che
+la risorsa è disponibile, la funzione ha successo, il valore del semaforo
+viene diminuito di 1 ed essa ritorna immediatamente consentendo la
+prosecuzione del processo.
+
+Se invece il valore è nullo la funzione si blocca (fermando l'esecuzione del
+processo) fintanto che il valore del semaforo non ritorna positivo (cosa che a
+questo punto può avvenire solo per opera di altro processo che rilascia il
+semaforo con una chiamata a \func{sem\_post}) così che poi essa possa
+decrementarlo con successo e proseguire.
+
+Si tenga presente che la funzione può sempre essere interrotta da un segnale,
+nel qual caso si avrà un errore di \errval{EINTR}; inoltre questo avverrà
+comunque, anche qualora si fosse richiesta la gestione con la semantica BSD,
+installando il gestore del suddetto segnale con l'opzione \const{SA\_RESTART}
+(vedi sez.~\ref{sec:sig_sigaction}) per riavviare le \textit{system call}
+interrotte.
+
+Della funzione \func{sem\_wait} esistono due varianti che consentono di
+gestire diversamente le modalità di attesa in caso di risorsa occupata, la
+prima di queste è \funcd{sem\_trywait}, che serve ad effettuare un tentativo
+di acquisizione senza bloccarsi; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_trywait(sem\_t *sem)}
+
+\fdesc{Tenta di bloccare un semaforo.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EAGAIN}] il semaforo non può essere acquisito senza
+ bloccarsi.
+ \item[\errcode{EINVAL}] l'argomento \param{sem} non indica un semaforo
+ valido.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione è identica a \func{sem\_wait} ed se la risorsa è libera ha lo
+stesso effetto, vale a dire che in caso di semaforo diverso da zero la
+funzione lo decrementa e ritorna immediatamente; la differenza è che nel caso
+in cui il semaforo è occupato essa non si blocca e di nuovo ritorna
+immediatamente, restituendo però un errore di \errval{EAGAIN}, così che il
+programma possa proseguire.
+
+La seconda variante di \func{sem\_wait} è una estensione specifica che può
+essere utilizzata soltanto se viene definita la macro \macro{\_XOPEN\_SOURCE}
+ad un valore di almeno 600 o la macro \macro{\_POSIX\_C\_SOURCE} ad un valore
+uguale o maggiore di \texttt{200112L} prima di includere
+\headfiled{semaphore.h}, la funzione è \funcd{sem\_timedwait}, ed il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_timedwait(sem\_t *sem, const struct timespec
+ *abs\_timeout)}
+
+\fdesc{Blocca un semaforo.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+ \item[\errcode{EINVAL}] l'argomento \param{sem} non indica un semaforo
+ valido.
+ \item[\errcode{ETIMEDOUT}] è scaduto il tempo massimo di attesa.
+ \end{errlist}
+}
+\end{funcproto}
+
+Anche in questo caso il comportamento della funzione è identico a quello di
+\func{sem\_wait}, ma è possibile impostare un tempo limite per l'attesa
+tramite la struttura \struct{timespec} (vedi
+fig.~\ref{fig:sys_timespec_struct}) puntata
+dall'argomento \param{abs\_timeout}, indicato in secondi e nanosecondi a
+partire dalla cosiddetta \textit{Epoch} (00:00:00, 1 January 1970
+UTC). Scaduto il limite la funzione ritorna anche se non è possibile acquisire
+il semaforo fallendo con un errore di \errval{ETIMEDOUT}.
+
+La seconda funzione principale utilizzata per l'uso dei semafori è quella che
+viene usata per rilasciare un semaforo occupato o, in generale, per aumentare
+di una unità il valore dello stesso anche qualora non fosse occupato (si
+ricordi che in generale un semaforo viene usato come indicatore di un numero
+di risorse disponibili). Detta funzione è \funcd{sem\_post} ed il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_post(sem\_t *sem)}
+
+\fdesc{Rilascia un semaforo.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] l'argomento \param{sem} non indica un semaforo
+ valido.
+ \item[\errcode{EOVERFLOW}] si superato il massimo valore di un semaforo.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione incrementa di uno il valore corrente del semaforo indicato
+dall'argomento \param{sem}, se questo era nullo la relativa risorsa risulterà
+sbloccata, cosicché un altro processo (o \textit{thread}) eventualmente
+bloccato in una \func{sem\_wait} sul semaforo possa essere svegliato e rimesso
+in esecuzione. Si tenga presente che la funzione è sicura per l'uso
+all'interno di un gestore di segnali (si ricordi quanto detto in
+sez.~\ref{sec:sig_signal_handler}).
+
+Se invece di operare su un semaforo se ne volesse semplicemente leggere il
+valore, si potrà usare la funzione \funcd{sem\_getvalue}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_getvalue(sem\_t *sem, int *sval)}
+
+\fdesc{Richiede il valore di un semaforo.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] l'argomento \param{sem} non indica un semaforo
+ valido.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione legge il valore del semaforo indicato dall'argomento \param{sem} e
+lo restituisce nella variabile intera puntata dall'argomento
+\param{sval}. Qualora ci siano uno o più processi bloccati in attesa sul
+semaforo lo standard prevede che la funzione possa restituire un valore nullo
+oppure il numero di processi bloccati in una \func{sem\_wait} sul suddetto
+semaforo; nel caso di Linux vale la prima opzione.
+
+Questa funzione può essere utilizzata per avere un suggerimento sullo stato di
+un semaforo, ovviamente non si può prendere il risultato riportato in
+\param{sval} che come indicazione, il valore del semaforo infatti potrebbe
+essere già stato modificato al ritorno della funzione.
+
+% TODO verificare comportamento sem_getvalue
+
+Una volta che non ci sia più la necessità di operare su un semaforo se ne può
+terminare l'uso con la funzione \funcd{sem\_close}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_close(sem\_t *sem)}
+
+\fdesc{Chiude un semaforo.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] l'argomento \param{sem} non indica un semaforo
+ valido.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione chiude il semaforo indicato dall'argomento \param{sem}, che non
+potrà più essere utilizzato nelle altre funzioni. La chiusura comporta anche
+che tutte le risorse che il sistema poteva avere assegnato al processo
+nell'uso del semaforo vengono immediatamente rilasciate. Questo significa che
+un eventuale altro processo bloccato sul semaforo a causa della acquisizione
+dello stesso da parte del processo che chiama \func{sem\_close} potrà essere
+immediatamente riavviato.
+
+Si tenga presente poi che come avviene per i file, all'uscita di un processo
+anche tutti i semafori che questo aveva aperto vengono automaticamente chiusi.
+Questo comportamento risolve il problema che si aveva con i semafori del
+\textit{SysV IPC} (di cui si è parlato in sez.~\ref{sec:ipc_sysv_sem}) per i
+quali le risorse possono restare bloccate. Si tenga infine presente che, a
+differenza di quanto avviene per i file, in caso di una chiamata ad
+\func{execve} tutti i semafori vengono chiusi automaticamente.
+
+Come per i semafori del \textit{SysV-IPC} anche quelli POSIX hanno una
+persistenza di sistema; questo significa che una volta che si è creato un
+semaforo con \func{sem\_open} questo continuerà ad esistere fintanto che il
+kernel resta attivo (vale a dire fino ad un successivo riavvio) a meno che non
+lo si cancelli esplicitamente. Per far questo si può utilizzare la funzione
+\funcd{sem\_unlink}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_unlink(const char *name)}
+
+\fdesc{Rimuove un semaforo.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EACCES}] non si hanno i permessi necessari a cancellare il
+ semaforo.
+ \item[\errcode{ENAMETOOLONG}] il nome indicato è troppo lungo.
+ \item[\errcode{ENOENT}] il semaforo \param{name} non esiste.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione rimuove il semaforo indicato dall'argomento \param{name}, che
+prende un valore identico a quello usato per creare il semaforo stesso con
+\func{sem\_open}. Il semaforo viene rimosso dal filesystem immediatamente; ma
+il semaforo viene effettivamente cancellato dal sistema soltanto quando tutti
+i processi che lo avevano aperto lo chiudono. Si segue cioè la stessa
+semantica usata con \func{unlink} per i file, trattata in dettaglio in
+sez.~\ref{sec:link_symlink_rename}.
+
+Una delle caratteristiche peculiari dei semafori POSIX è che questi possono
+anche essere utilizzati anche in forma anonima, senza necessità di fare
+ricorso ad un nome sul filesystem o ad altri indicativi. In questo caso si
+dovrà porre la variabile che contiene l'indirizzo del semaforo in un tratto di
+memoria che sia accessibile a tutti i processi in gioco. La funzione che
+consente di inizializzare un semaforo anonimo è \funcd{sem\_init}, il cui
+prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_init(sem\_t *sem, int pshared, unsigned int value)}
+\fdesc{Inizializza un semaforo anonimo.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] il valore di \param{value} eccede
+ \const{SEM\_VALUE\_MAX}.
+ \item[\errcode{ENOSYS}] il valore di \param{pshared} non è nullo ed il
+ sistema non supporta i semafori per i processi.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione inizializza un semaforo all'indirizzo puntato dall'argomento
+\param{sem}, e come per \func{sem\_open} consente di impostare un valore
+iniziale con \param{value}. L'argomento \param{pshared} serve ad indicare se
+il semaforo deve essere utilizzato dai \textit{thread} di uno stesso processo
+(con un valore nullo) o condiviso fra processi diversi (con un valore non
+nullo).
+
+Qualora il semaforo debba essere condiviso dai \textit{thread} di uno stesso
+processo (nel qual caso si parla di \textit{thread-shared semaphore}),
+occorrerà che \param{sem} sia l'indirizzo di una variabile visibile da tutti i
+\textit{thread}, si dovrà usare cioè una variabile globale o una variabile
+allocata dinamicamente nello \textit{heap}.
+
+Qualora il semaforo debba essere condiviso fra più processi (nel qual caso si
+parla di \textit{process-shared semaphore}) la sola scelta possibile per
+renderlo visibile a tutti è di porlo in un tratto di memoria condivisa. Questo
+potrà essere ottenuto direttamente sia con \func{shmget} (vedi
+sez.~\ref{sec:ipc_sysv_shm}) che con \func{shm\_open} (vedi
+sez.~\ref{sec:ipc_posix_shm}), oppure, nel caso che tutti i processi in gioco
+abbiano un genitore comune, con una mappatura anonima con \func{mmap} (vedi
+sez.~\ref{sec:file_memory_map}) a cui essi poi potranno accedere (si ricordi
+che i tratti di memoria condivisa vengono mantenuti nei processi figli
+attraverso la funzione \func{fork}).
+
+Una volta inizializzato il semaforo anonimo con \func{sem\_init} lo si potrà
+utilizzare nello stesso modo dei semafori normali con \func{sem\_wait} e
+\func{sem\_post}. Si tenga presente però che inizializzare due volte lo stesso
+semaforo può dar luogo ad un comportamento indefinito.
+
+Qualora non si intenda più utilizzare un semaforo anonimo questo può essere
+eliminato dal sistema; per far questo di deve utilizzare una apposita
+funzione, \funcd{sem\_destroy}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_destroy(sem\_t *sem)}
+\fdesc{Elimina un semaforo anonimo.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] l'argomento \param{sem} non indica un semaforo
+ valido.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione prende come unico argomento l'indirizzo di un semaforo che deve
+essere stato inizializzato con \func{sem\_init}; non deve quindi essere
+applicata a semafori creati con \func{sem\_open}. Inoltre si deve essere
+sicuri che il semaforo sia effettivamente inutilizzato, la distruzione di un
+semaforo su cui sono presenti processi (o \textit{thread}) in attesa (cioè
+bloccati in una \func{sem\_wait}) provoca un comportamento indefinito.
+
+Si tenga presente infine che utilizzare un semaforo che è stato distrutto con
+\func{sem\_destroy} di nuovo può dare esito a comportamenti indefiniti. Nel
+caso ci si trovi in una tale evenienza occorre reinizializzare il semaforo una
+seconda volta con \func{sem\_init}.
+
+Come esempio di uso sia della memoria condivisa che dei semafori POSIX si sono
+scritti due semplici programmi con i quali è possibile rispettivamente
+monitorare il contenuto di un segmento di memoria condivisa e modificarne il
+contenuto.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/message_getter.c}
+ \end{minipage}
+ \normalsize
+ \caption{Sezione principale del codice del programma
+ \file{message\_getter.c}.}
+ \label{fig:ipc_posix_sem_shm_message_server}
+\end{figure}
+
+Il corpo principale del primo dei due, il cui codice completo è nel file
+\file{message\_getter.c} dei sorgenti allegati, è riportato in
+fig.~\ref{fig:ipc_posix_sem_shm_message_server}; si è tralasciata la parte che
+tratta la gestione delle opzioni a riga di comando (che consentono di
+impostare un nome diverso per il semaforo e il segmento di memoria condivisa)
+ed il controllo che al programma venga fornito almeno un argomento, contenente
+la stringa iniziale da inserire nel segmento di memoria condivisa.
+
+Lo scopo del programma è quello di creare un segmento di memoria condivisa su
+cui registrare una stringa, e tenerlo sotto osservazione stampando la stessa
+una volta al secondo. Si utilizzerà un semaforo per proteggere l'accesso in
+lettura alla stringa, in modo che questa non possa essere modificata
+dall'altro programma prima di averla finita di stampare.
+
+La parte iniziale del programma contiene le definizioni (\texttt{\small 1-8})
+del gestore del segnale usato per liberare le risorse utilizzate, delle
+variabili globali contenenti i nomi di default del segmento di memoria
+condivisa e del semaforo (il default scelto è \texttt{messages}), e delle
+altre variabili utilizzate dal programma.
+
+Come prima istruzione (\texttt{\small 10}) si è provveduto ad installare un
+gestore di segnale che consentirà di effettuare le operazioni di pulizia
+(usando la funzione \func{Signal} illustrata in
+fig.~\ref{fig:sig_Signal_code}), dopo di che (\texttt{\small 12-16}) si è
+creato il segmento di memoria condivisa con la funzione \func{CreateShm} che
+abbiamo appena trattato in sez.~\ref{sec:ipc_posix_shm}, uscendo con un
+messaggio in caso di errore.
+
+Si tenga presente che la funzione \func{CreateShm} richiede che il segmento
+non sia già presente e fallirà qualora un'altra istanza, o un altro programma
+abbia già allocato un segmento con quello stesso nome. Per semplicità di
+gestione si è usata una dimensione fissa pari a 256 byte, definita tramite la
+costante \texttt{MSGMAXSIZE}.
+
+Il passo successivo (\texttt{\small 17-21}) è quello della creazione del
+semaforo che regola l'accesso al segmento di memoria condivisa con
+\func{sem\_open}; anche in questo caso si gestisce l'uscita con stampa di un
+messaggio in caso di errore. Anche per il semaforo, avendo specificato la
+combinazione di flag \code{O\_CREAT|O\_EXCL} come secondo argomento, si esce
+qualora fosse già esistente; altrimenti esso verrà creato con gli opportuni
+permessi specificati dal terzo argomento, (indicante lettura e scrittura in
+notazione ottale). Infine il semaforo verrà inizializzato ad un valore nullo
+(il quarto argomento), corrispondete allo stato in cui risulta bloccato.
+
+A questo punto (\texttt{\small 22}) si potrà inizializzare il messaggio posto
+nel segmento di memoria condivisa usando la stringa passata come argomento al
+programma. Essendo il semaforo stato creato già bloccato non ci si dovrà
+preoccupare di eventuali \textit{race condition} qualora il programma di
+modifica del messaggio venisse lanciato proprio in questo momento. Una volta
+inizializzato il messaggio occorrerà però rilasciare il semaforo
+(\texttt{\small 24-27}) per consentirne l'uso; in tutte queste operazioni si
+provvederà ad uscire dal programma con un opportuno messaggio in caso di
+errore.
+
+Una volta completate le inizializzazioni il ciclo principale del programma
+(\texttt{\small 29-47}) viene ripetuto indefinitamente (\texttt{\small 29})
+per stampare sia il contenuto del messaggio che una serie di informazioni di
+controllo. Il primo passo (\texttt{\small 30-34}) è quello di acquisire (con
+\func{sem\_getvalue}, con uscita in caso di errore) e stampare il valore del
+semaforo ad inizio del ciclo; seguito (\texttt{\small 35-36}) dal tempo
+corrente.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/HandSigInt.c}
+ \end{minipage}
+ \normalsize
+ \caption{Codice del gestore di segnale del programma
+ \file{message\_getter.c}.}
+ \label{fig:ipc_posix_sem_shm_message_server_handler}
+\end{figure}
+
+Prima della stampa del messaggio invece si deve acquisire il semaforo
+(\texttt{\small 30-33}) per evitare accessi concorrenti alla stringa da parte
+del programma di modifica. Una volta eseguita la stampa (\texttt{\small 41})
+il semaforo dovrà essere rilasciato (\texttt{\small 42-45}). Il passo finale
+(\texttt{\small 46}) è attendere per un secondo prima di eseguire da capo il
+ciclo.
+
+Per uscire in maniera corretta dal programma sarà necessario fermarlo con una
+interruzione da tastiera (\texttt{C-c}), che corrisponde all'invio del segnale
+\signal{SIGINT}, per il quale si è installato (\texttt{\small 10}) una
+opportuna funzione di gestione, riportata in
+fig.~\ref{fig:ipc_posix_sem_shm_message_server_handler}. La funzione è molto
+semplice e richiama le funzioni di rimozione sia per il segmento di memoria
+condivisa che per il semaforo, garantendo così che possa essere riaperto
+ex-novo senza errori in un futuro riutilizzo del comando.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/message_setter.c}
+ \end{minipage}
+ \normalsize
+ \caption{Sezione principale del codice del programma
+ \file{message\_setter.c}.}
+ \label{fig:ipc_posix_sem_shm_message_setter}
+\end{figure}
+
+Il secondo programma di esempio è \file{message\_setter.c}, di cui si è
+riportato il corpo principale in
+fig.~\ref{fig:ipc_posix_sem_shm_message_setter},\footnote{al solito il codice
+ completo è nel file dei sorgenti allegati.} dove si è tralasciata, non
+essendo significativa per quanto si sta trattando, la parte relativa alla
+gestione delle opzioni a riga di comando e degli argomenti, che sono identici
+a quelli usati da \file{message\_getter}, con l'unica aggiunta di un'opzione
+``\texttt{-t}'' che consente di indicare un tempo di attesa (in secondi) in
+cui il programma si ferma tenendo bloccato il semaforo.
+
+Una volta completata la gestione delle opzioni e degli argomenti (ne deve
+essere presente uno solo, contenente la nuova stringa da usare come
+messaggio), il programma procede (\texttt{\small 10-14}) con l'acquisizione
+del segmento di memoria condivisa usando la funzione \func{FindShm} (trattata
+in sez.~\ref{sec:ipc_posix_shm}) che stavolta deve già esistere. Il passo
+successivo (\texttt{\small 16-19}) è quello di aprire il semaforo, e a
+differenza di \file{message\_getter}, in questo caso si richiede a
+\func{sem\_open} che questo esista, passando uno zero come secondo ed unico
+argomento.
+
+Una volta completate con successo le precedenti inizializzazioni, il passo
+seguente (\texttt{\small 21-24}) è quello di acquisire il semaforo, dopo di
+che sarà possibile eseguire la sostituzione del messaggio (\texttt{\small 25})
+senza incorrere in possibili \textit{race condition} con la stampa dello
+stesso da parte di \file{message\_getter}.
+
+Una volta effettuata la modifica viene stampato (\texttt{\small 26}) il tempo
+di attesa impostato con l'opzione ``\texttt{-t}'' dopo di che (\texttt{\small
+ 27}) viene eseguita la stessa, senza rilasciare il semaforo che resterà
+quindi bloccato (causando a questo punto una interruzione delle stampe
+eseguite da \file{message\_getter}). Terminato il tempo di attesa si rilascerà
+(\texttt{\small 29-32}) il semaforo per poi uscire.
+
+Per verificare il funzionamento dei programmi occorrerà lanciare prima
+\file{message\_getter} (lanciare per primo \file{message\_setter} darebbe
+luogo ad un errore, non essendo stati creati il semaforo ed il segmento di
+memoria condivisa) che inizierà a stampare una volta al secondo il contenuto
+del messaggio ed i suoi dati, con qualcosa del tipo:
+\begin{Console}
+piccardi@hain:~/gapil/sources$ \textbf{./message_getter messaggio}
+sem=1, Fri Dec 31 14:12:41 2010
+message: messaggio
+sem=1, Fri Dec 31 14:12:42 2010
+message: messaggio
+...
+\end{Console}
+%$
+proseguendo indefinitamente fintanto che non si prema \texttt{C-c} per farlo
+uscire. Si noti come il valore del semaforo risulti sempre pari ad 1 (in
+quanto al momento esso sarà sempre libero).
+
+A questo punto si potrà lanciare \file{message\_setter} per cambiare il
+messaggio, nel nostro caso per rendere evidente il funzionamento del blocco
+richiederemo anche una attesa di 3 secondi, ed otterremo qualcosa del tipo:
+\begin{Console}
+piccardi@hain:~/gapil/sources$ \textbf{./message_setter -t 3 ciao}
+Sleeping for 3 seconds
+\end{Console}
+%$
+dove il programma si fermerà per 3 secondi prima di rilasciare il semaforo e
+terminare. L'effetto di tutto ciò si potrà vedere nell'\textit{output} di
+\file{message\_getter}, che verrà interrotto per questo stesso tempo, prima di
+ricominciare con il nuovo testo:
+\begin{Console}
+...
+sem=1, Fri Dec 31 14:16:27 2010
+message: messaggio
+sem=1, Fri Dec 31 14:16:28 2010
+message: messaggio
+sem=0, Fri Dec 31 14:16:29 2010
+message: ciao
+sem=1, Fri Dec 31 14:16:32 2010
+message: ciao
+sem=1, Fri Dec 31 14:16:33 2010
+message: ciao
+...
+\end{Console}
+%$
+
+E si noterà come nel momento in cui si lancia \file{message\_setter} le stampe
+di \file{message\_getter} si bloccheranno, come corretto, dopo aver registrato
+un valore nullo per il semaforo. Il programma infatti resterà bloccato nella
+\func{sem\_wait} (quella di riga (\texttt{\small 37}) in
+fig.~\ref{fig:ipc_posix_sem_shm_message_server}) fino alla scadenza
+dell'attesa di \file{message\_setter} (con l'esecuzione della \func{sem\_post}
+della riga (\texttt{\small 29}) di
+fig.~\ref{fig:ipc_posix_sem_shm_message_setter}), e riprenderanno con il nuovo
+testo alla terminazione di quest'ultimo.
+