Risistemata flock, aggiunta figura sulla struttura del sistema
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 1116f2e3634111f717c899ef9e71cb683f31bcb2..1502f34f3fe6cde7cf60c807c12bc45d592f15b4 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -56,7 +56,7 @@ accennato concetto di funzionamento di una pipe 
 scrive nel file descriptor aperto in scrittura viene ripresentato tale e quale
 nel file descriptor aperto in lettura. I file descriptor infatti non sono
 connessi a nessun file reale, ma ad un buffer nel kernel, la cui dimensione è
-specificata dalla costante \macro{PIPE\_BUF}, (vedi
+specificata dal parametro di sistema \macro{PIPE\_BUF}, (vedi
 \secref{sec:sys_file_limits}). Lo schema di funzionamento di una pipe è
 illustrato in \figref{fig:ipc_pipe_singular}, in cui sono illustrati i due
 capi della pipe, associati a ciascun file descriptor, con le frecce che
@@ -786,7 +786,6 @@ dal server siano sempre di dimensioni inferiori a \macro{PIPE\_BUF},
 tralasciamo la gestione del caso in cui questo non è vero. Infine si stampa
 (\texttt{\small 32}) a video la risposta, si chiude (\texttt{\small 33}) la
 fifo e si cancella (\texttt{\small 34}) il relativo file.
-
 Si noti come la fifo per la risposta sia stata aperta solo dopo aver inviato
 la richiesta, se non si fosse fatto così si avrebbe avuto uno stallo, in
 quanto senza la richiesta, il server non avrebbe potuto aprirne il capo in
@@ -808,6 +807,57 @@ come quelli che esamineremo in seguito.
 
 
 
+\subsection{La funzione \func{socketpair}}
+\label{sec:ipc_socketpair}
+
+Un meccanismo di comunicazione molto simile alle pipe, ma che non presenta il
+problema della unidirezionalità del flusso dei dati, è quello dei cosiddetti
+\textit{socket} locali (o \textit{Unix domain socket}). Tratteremo l'argomento
+dei socket in \capref{cha:socket_intro}, nell'ambito dell'interfaccia generale
+che essi forniscono per la programmazione di rete; e vedremo
+(in~\secref{sec:sock_sa_local}) come in tal caso si possono definire dei file
+speciali (di tipo \textit{socket}, analoghi alle fifo) cui si accede però
+attraverso quella interfaccia; vale però la pena esaminare qui una
+modalità\footnote{la funzione \func{socketpair} è stata introdotta in BSD4.4,
+  ma è supportata in genere da qualunque sistema che fornisca l'interfaccia
+  dei socket.} di uso di questi socket che li rende sostanzialmente identici
+ad una pipe bidirezionale.
+
+Attraverso la funzione \func{socketpair} infatti è possibile creare una coppia
+di socket (che sono trattati com file descriptor) connessi fra di loro, senza
+fare nessun riferimento ad un file speciale sul filesystem, in maniera analoga
+a quello che si fa con \func{pipe}; la differenza è che in questo caso il
+flusso dei dati è bidirezionale. Il prototipo della funzione è:
+\begin{functions}
+  \headdecl{sys/types.h} 
+  \headdecl{sys/socket.h} 
+  
+  \funcdecl{int socketpair(int domain, int type, int protocol, int sv[2])}
+  
+  Crea una coppia di socket connessi fra loro.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\macro{EAFNOSUPPORT}] I socket locali non sono supportati.
+  \item[\macro{EPROTONOSUPPORT}] Il protocollo specificato non è supportato.
+  \item[\macro{EOPNOTSUPP}] Il protocollo specificato non supporta la
+  creazione di coppie di socket.
+  \end{errlist}
+  ed inoltre \macro{EMFILE},  \macro{EFAULT}.
+}
+\end{functions}
+
+La funzione restituisce in \param{sv} una coppia di descrittori di socket
+(come vedremo in \capref{cha:socket_intro} i file descriptor vengono usati
+anche per i socket) connessi fra di loro, così che quello che si scrive da una
+parte può essere riletto dall'altra e viceversa. I parametri \param{domain},
+\param{type} e \param{protocol} derivano dall'interfaccia dei socket, ma in
+questo caso i soli valori validi sono rispettivamente \macro{AF\_UNIX},
+\macro{SOCK\_STREAM} e \macro{0}.
+
+
+
 \section{La comunicazione fra processi di System V}
 \label{sec:ipc_sysv}
 
@@ -1162,7 +1212,7 @@ una 
   
   \funcdecl{int msgget(key\_t key, int flag)}
   
-  Restituisce l'identificatore di una cosa di messaggi.
+  Restituisce l'identificatore di una coda di messaggi.
   
   \bodydesc{La funzione restituisce l'identificatore (un intero positivo) o -1
     in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
@@ -1438,7 +1488,7 @@ argomento 
 cioè \var{message} è una propria struttura che si passa alla funzione,
 \param{msgsz} dovrà essere uguale a \code{sizeof(message)-sizeof(long)}, (se
 consideriamo il caso dell'esempio in \figref{fig:ipc_msbuf}, \param{msgsz}
-dovrà essere pari a \macro{LENGHT}).
+dovrà essere pari a \macro{LENGTH}).
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1485,12 +1535,12 @@ interrotta da un segnale (nel qual caso si ha un errore di \macro{EINTR}).
 Una volta completato con successo l'invio del messaggio sulla coda, la
 funzione aggiorna i dati mantenuti in \var{msqid\_ds}, in particolare vengono
 modificati:
-\begin{itemize}
+\begin{itemize*}
 \item Il valore di \var{msg\_lspid}, che viene impostato al \acr{pid} del
   processo chiamante.
 \item Il valore di \var{msg\_qnum}, che viene incrementato di uno.
 \item Il valore \var{msg\_stime}, che viene impostato al tempo corrente.
-\end{itemize}
+\end{itemize*}
 
 
 La funzione che permette di estrarre da una coda un messaggio (che sarà
@@ -1525,7 +1575,7 @@ rimosso dalla stessa) 
 La funzione legge un messaggio dalla coda specificata scrivendolo nel buffer
 indicato da \param{msgp}, che avrà un formato analogo a quello di
 \figref{fig:ipc_msbuf}. L'argomento \param{msgsz} indica la lunghezza massima
-del testo del messaggio (equivalente al valore del parametro \macro{LENGHT}
+del testo del messaggio (equivalente al valore del parametro \macro{LENGTH}
 nell'esempio di \figref{fig:ipc_msbuf}).
 
 Se il testo del messaggio ha lunghezza inferiore a \param{msgsz} esso viene
@@ -1540,7 +1590,7 @@ una scansione della struttura mostrata in \figref{fig:ipc_mq_schema},
 restituendo il primo messaggio incontrato che corrisponde ai criteri
 specificati (che quindi, visto che i messaggi vengono sempre inseriti dalla
 coda, è quello meno recente); in particolare:
-\begin{itemize}
+\begin{itemize*}
 \item se \param{msgtyp} è 0 viene estratto il messaggio in cima alla coda, cioè
   quello fra i presenti che è stato inserito inserito per primo. 
 \item se \param{msgtyp} è positivo viene estratto il primo messaggio il cui
@@ -1549,7 +1599,7 @@ coda, 
 \item se \param{msgtyp} è negativo viene estratto il primo fra i messaggi con
   il tipo di valore più basso, fra tutti quelli con un tipo inferiore al
   valore assoluto di \param{msgtyp}.
-\end{itemize}
+\end{itemize*}
 
 Il valore di \param{msgflg} permette di controllare il comportamento della
 funzione, esso può essere nullo o una maschera binaria composta da uno o più
@@ -1571,12 +1621,12 @@ segnale (con \var{errno} impostata a \macro{EINTR}).
 Una volta completata con successo l'estrazione del messaggio dalla coda, la
 funzione aggiorna i dati mantenuti in \var{msqid\_ds}, in particolare vengono
 modificati:
-\begin{itemize}
+\begin{itemize*}
 \item Il valore di \var{msg\_lrpid}, che viene impostato al \acr{pid} del
   processo chiamante.
 \item Il valore di \var{msg\_qnum}, che viene decrementato di uno.
 \item Il valore \var{msg\_rtime}, che viene impostato al tempo corrente.
-\end{itemize}
+\end{itemize*}
 
 Come esempio dell'uso delle code di messaggi possiamo riscrivere il nostro
 server di \textit{fortunes} usando queste al posto delle fifo. In questo caso
@@ -1594,9 +1644,9 @@ codice (si ricordi quanto detto in \secref{sec:proc_race_cond}).
 
 Un semaforo è uno speciale contatore, mantenuto nel kernel, che permette, a
 seconda del suo valore, di consentire o meno la prosecuzione dell'esecuzione
-del codice. In questo modo l'accesso ad una risorsa condivisa da più processi
-può essere controllato, associando ad essa un semaforo che consente di
-assicurare che non più di un processo alla volta possa usarla.
+di un programma. In questo modo l'accesso ad una risorsa condivisa da più
+processi può essere controllato, associando ad essa un semaforo che consente
+di assicurare che non più di un processo alla volta possa usarla.
 
 Il concetto di semaforo è uno dei concetti base nella programmazione ed è
 assolutamente generico, così come del tutto generali sono modalità con cui lo
@@ -1655,9 +1705,9 @@ Purtroppo questa implementazione complica inutilmente lo schema elementare che
 abbiamo descritto, dato che non è possibile definire un singolo semaforo, ma
 se ne deve creare per forza un insieme.  Ma questa in definitiva è solo una
 complicazione inutile, il problema è che i semafori del System V IPC soffrono
-di altri due ben più gravi difetti.
+di altri due, ben più gravi, difetti.
 
-Il primo grave difetto è che non esiste una funzione che permetta di creare ed
+Il primo difetto è che non esiste una funzione che permetta di creare ed
 inizializzare un semaforo in un'unica chiamata; occorre prima creare l'insieme
 dei semafori con \func{semget} e poi inizializzarlo con \func{semctl}, si
 perde così ogni possibilità di eseguire atomicamente questa operazione.
@@ -1804,9 +1854,13 @@ loro inizializzazione) 
 La funzione può avere tre o quattro parametri, a seconda dell'operazione
 specificata con \param{cmd}, ed opera o sull'intero insieme specificato da
 \param{semid} o sul singolo semaforo di un insieme, specificato da
-\param{semnum}. Qualora la funzione operi con quattro argomenti \param{arg} è
-un argomento generico che deve essere una \var{union semun}, si è riportato la
-relativa definizione in \figref{fig:ipc_semun}.
+\param{semnum}. 
+
+Qualora la funzione operi con quattro argomenti \param{arg} è
+un argomento generico, che conterrà un dato diverso a seconda dell'azione
+richiesta; per unificare l'argomento esso deve essere passato come una
+\var{union semun}, la cui definizione, con i possibili valori che può
+assumere, è riportata in \figref{fig:ipc_semun}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1827,9 +1881,11 @@ union semun {
   \label{fig:ipc_semun}
 \end{figure}
 
-Il comportamento della funzione, come il numero di parametri, dipende dal
-valore dell'argomento \param{cmd}, che specifica l'azione da intraprendere; i
-possibili valori legali per questo argomento sono:
+Come già accennato sia il comportamento della funzione che il numero di
+parametri con cui deve essere invocata, dipendono dal valore dell'argomento
+\param{cmd}, che specifica l'azione da intraprendere; i valori validi (che
+cioè non causano un errore di \macro{EINVAL}) per questo argomento sono i
+seguenti:
 \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
 \item[\macro{IPC\_STAT}] Legge i dati dell'insieme di semafori, copiando il
   contenuto della relativa struttura \var{semid\_ds} all'indirizzo specificato
@@ -1849,25 +1905,28 @@ possibili valori legali per questo argomento sono:
   corrispondere o al creatore o al proprietario dell'insieme, o
   all'amministratore.  L'argomento \param{semnum} viene ignorato.
 \item[\macro{GETALL}] Restituisce il valore corrente di ciascun semaforo
-  dell'insieme (il campo \var{semval} di \var{sem}) nel vettore indicato da
-  \param{arg.array}. Occorre avere il permesso di lettura. L'argomento
-  \param{semnum} viene ignorato.
+  dell'insieme (corrispondente al campo \var{semval} di \var{sem}) nel vettore
+  indicato da \param{arg.array}. Occorre avere il permesso di lettura.
+  L'argomento \param{semnum} viene ignorato.
 \item[\macro{GETNCNT}] Restituisce come valore di ritorno della funzione il
   numero di processi in attesa che il semaforo \param{semnum} dell'insieme
-  venga incrementato (il campo \var{semncnt} di \var{sem}); va invocata con
-  tre argomenti.  Occorre avere il permesso di lettura.
+  \param{semid} venga incrementato (corrispondente al campo \var{semncnt} di
+  \var{sem}); va invocata con tre argomenti.  Occorre avere il permesso di
+  lettura.
 \item[\macro{GETPID}] Restituisce come valore di ritorno della funzione il
   \acr{pid} dell'ultimo processo che ha compiuto una operazione sul semaforo
-  \param{semnum} dell'insieme (il campo \var{sempid} di \var{sem}); va
-  invocata con tre argomenti.  Occorre avere il permesso di lettura.
-\item[\macro{GETVAL}] Restituisce come valore di ritorno della funzione il il
-  valore corrente del semaforo \param{semnum} dell'insieme (il campo
-  \var{semval} di \var{sem}); va invocata con tre argomenti.  Occorre avere il
+  \param{semnum} dell'insieme \param{semid} (corrispondente al campo
+  \var{sempid} di \var{sem}); va invocata con tre argomenti.  Occorre avere il
   permesso di lettura.
+\item[\macro{GETVAL}] Restituisce come valore di ritorno della funzione il il
+  valore corrente del semaforo \param{semnum} dell'insieme \param{semid}
+  (corrispondente al campo \var{semval} di \var{sem}); va invocata con tre
+  argomenti.  Occorre avere il permesso di lettura.
 \item[\macro{GETZCNT}] Restituisce come valore di ritorno della funzione il
   numero di processi in attesa che il valore del semaforo \param{semnum}
-  dell'insieme diventi nullo (il campo \var{semncnt} di \var{sem}); va
-  invocata con tre argomenti.  Occorre avere il permesso di lettura.
+  dell'insieme \param{semid} diventi nullo (corrispondente al campo
+  \var{semncnt} di \var{sem}); va invocata con tre argomenti.  Occorre avere
+  il permesso di lettura.
 \item[\macro{SETALL}] Inizializza il valore di tutti i semafori dell'insieme,
   aggiornando il campo \var{sem\_ctime} di \var{semid\_ds}. I valori devono
   essere passati nel vettore indicato da \param{arg.array}.  Si devono avere i
@@ -1879,12 +1938,76 @@ possibili valori legali per questo argomento sono:
 \end{basedescript}
 
 Quando si imposta il valore di un semaforo (sia che lo si faccia per tutto
-l'insieme con \macro{SETALL}, che per uno solo con \macro{SETVAL}, i processi
-in attesa su di esso reagiscono di conseguenza al cambiamento di valore.
-Inoltre la coda delle operazioni di ripristino viene cancellata per tutti i
-semafori il cui valore viene modificato.
+l'insieme con \macro{SETALL}, che per un solo semaforo con \macro{SETVAL}), i
+processi in attesa su di esso reagiscono di conseguenza al cambiamento di
+valore.  Inoltre la coda delle operazioni di ripristino viene cancellata per
+tutti i semafori il cui valore viene modificato.
 
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|c|l|}
+    \hline
+    \textbf{Operazione}  & \textbf{Valore restituito} \\
+    \hline
+    \hline
+    \macro{GETNCNT}& valore di \var{semncnt}.\\
+    \macro{GETPID} & valore di \var{sempid}.\\
+    \macro{GETVAL} & valore di \var{semval}.\\
+    \macro{GETZCNT}& valore di \var{semzcnt}.\\
+    \hline
+  \end{tabular}
+  \caption{Valori di ritorno della funzione \func{semctl}.} 
+  \label{tab:ipc_semctl_returns}
+\end{table}
+
+Il valore di ritorno della funzione in caso di successo dipende
+dall'operazione richiesta; per tutte le operazioni che richiedono quattro
+argomenti esso è sempre nullo, per le altre operazioni, elencate in
+\tabref{tab:ipc_semctl_returns} viene invece restituito il valore richiesto,
+corrispondente al campo della struttura \var{sem} indicato nella seconda
+colonna della tabella.
+
+Le operazioni ordinarie sui semafori, come l'acquisizione o il rilascio degli
+stessi (in sostanza tutte quelle non comprese nell'uso di \func{semctl})
+vengono effettuate con la funzione \func{semop}, il cui prototipo è:
+\begin{functions}
+  \headdecl{sys/types.h} 
+  \headdecl{sys/ipc.h} 
+  \headdecl{sys/sem.h} 
+  
+  \funcdecl{int semop(int semid, struct sembuf *sops, unsigned nsops)}
+  
+  Esegue le operazioni ordinarie su un semaforo o un insieme di semafori.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà uno dei valori:
+    \begin{errlist}
+    \item[\macro{EACCES}] Il processo non ha i privilegi per eseguire
+      l'operazione richiesta.
+    \item[\macro{EIDRM}] L'insieme di semafori è stato cancellato.
+    \item[\macro{ENOMEM}] Si è richiesto un \macro{SEM\_UNDO} ma il sistema
+      non ha le risorse per allocare la struttura di ripristino.
+    \item[\macro{EAGAIN}] Un'operazione comporterebbe il blocco del processo,
+      ma si è specificato \macro{IPC\_NOWAIT} in \var{sem\_flg}.
+    \item[\macro{EINTR}] La funzione, bloccata in attesa dell'esecuzione
+      dell'operazione, viene interrotta da un segnale.
+    \item[\macro{E2BIG}] L'argomento \param{nsops} è maggiore del numero
+      massimo di operazioni \macro{SEMOPM}.
+    \item[\macro{ERANGE}] Per alcune operazioni il valore risultante del
+      semaforo viene a superare il limite massimo \macro{SEMVMX}.
+  \end{errlist}
+  ed inoltre \macro{EFAULT} ed \macro{EINVAL}.
+}
+\end{functions}
 
+La funzione permette di eseguire operazioni multiple sui singoli semafori di
+un insieme. La funzione richiede come primo argomento l'identificatore
+\param{semid} dell'insieme su cui si vuole operare. Il numero di operazioni da
+effettuare viene specificato con l'argomento \param{nsop}, mentre il loro
+contenuto viene passato con un puntatore ad un vettore di strutture
+\var{sembuf} nell'argomento \param{sops}. Le operazioni richieste vengono
+effettivamente eseguite se e soltanto se è possibile effettuarle tutte quante.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1904,7 +2027,107 @@ struct sembuf
   \label{fig:ipc_sembuf}
 \end{figure}
 
+Il contenuto di ciascuna operazione deve essere specificato attraverso una
+opportuna struttura \var{sembuf} (la cui definizione è riportata in
+\figref{fig:ipc_sembuf}) che il programma chiamante deve avere cura di
+allocare in un opportuno vettore. La struttura permette di indicare il
+semaforo su cui operare, il tipo di operazione, ed un flag di controllo.
+
+Il campo \var{sem\_num} serve per indicare a quale semaforo dell'insieme fa
+riferimento l'operazione; si ricordi che i semafori sono numerati come in un
+vettore, per cui il primo semaforo corrisponde ad un valore nullo di
+\var{sem\_num}.
+
+Il campo \var{sem\_flg} è un flag, mantenuto come maschera binaria, per il
+quale possono essere impostati i due valori \macro{IPC\_NOWAIT} e
+\macro{SEM\_UNDO}.  Impostando \macro{IPC\_NOWAIT} si fa si che, invece di
+bloccarsi (in tutti quei casi in cui l'esecuzione di una operazione richiede
+che il processo vada in stato di \textit{sleep}), \func{semop} ritorni
+immediatamente con un errore di \macro{EAGAIN}.  Impostando \macro{SEM\_UNDO}
+si richiede invece che l'operazione venga registrata in modo che il valore del
+semaforo possa essere ripristinato all'uscita del processo.
+
+Infine \var{sem\_op} è il campo che controlla l'operazione che viene eseguita
+e determina il comportamento della chiamata a \func{semop}; tre sono i casi
+possibili:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\var{sem\_op}$>0$] In questo caso il valore di \var{sem\_op} viene
+  aggiunto al valore corrente di \var{semval}. La funzione ritorna
+  immediatamente (con un errore di \macro{ERANGE} qualora si sia superato il
+  limite \macro{SEMVMX}) ed il processo non viene bloccato in nessun caso.
+  Specificando \macro{SEM\_UNDO} si aggiorna il contatore per il ripristino
+  del valore del semaforo. Al processo chiamante è richiesto il privilegio di
+  alterazione (scrittura) sull'insieme di semafori.
+  
+\item[\var{sem\_op}$=0$] Nel caso \var{semval} sia zero l'esecuzione procede
+  immediatamente. Se \var{semval} è diverso da zero il comportamento è
+  controllato da \var{sem\_flg}, se è stato impostato \macro{IPC\_NOWAIT} la
+  funzione ritorna con un errore di \macro{EAGAIN}, altrimenti viene
+  incrementato \var{semzcnt} di uno ed il processo resta in stato di
+  \textit{sleep} fintanto che non si ha una delle condizioni seguenti:
+  \begin{itemize*}
+  \item \var{semval} diventa zero, nel qual caso \var{semzcnt} viene
+    decrementato di uno.
+  \item l'insieme di semafori viene rimosso, nel qual caso \func{semop} ritorna
+    un errore di \macro{EIDRM}.
+  \item il processo chiamante riceve un segnale, nel qual caso \var{semzcnt}
+    viene decrementato di uno e \func{semop} ritorna un errore di
+    \macro{EINTR}.
+  \end{itemize*}
+  Al processo chiamante è richiesto il privilegio di lettura dell'insieme dei
+  semafori.
+  
+\item[\var{sem\_op}$<0$] Nel caso in cui \var{semval} è maggiore o uguale del
+  valore assoluto di \var{sem\_op} (se cioè la somma dei due valori resta
+  positiva o nulla) i valori vengono sommati e la funzione ritorna
+  immediatamente; qualora si sia impostato \macro{SEM\_UNDO} viene anche
+  aggiornato il contatore per il ripristino del valore del semaforo. In caso
+  contrario (quando cioè la somma darebbe luogo ad un valore di \var{semval}
+  negativo) se si è impostato \macro{IPC\_NOWAIT} la funzione ritorna con un
+  errore di \macro{EAGAIN}, altrimenti viene incrementato di uno \var{semncnt}
+  ed il processo resta in stato di \textit{sleep} fintanto che non si ha una
+  delle condizioni seguenti:
+  \begin{itemize*}
+  \item \var{semval} diventa maggiore o uguale del valore assoluto di
+    \var{sem\_op}, nel qual caso \var{semncnt} viene decrementato di uno, il
+    valore di \var{sem\_op} viene sommato a \var{semval}, e se era stato
+    impostato \macro{SEM\_UNDO} viene aggiornato il contatore per il
+    ripristino del valore del semaforo.
+  \item l'insieme di semafori viene rimosso, nel qual caso \func{semop} ritorna
+    un errore di \macro{EIDRM}.
+  \item il processo chiamante riceve un segnale, nel qual caso \var{semncnt}
+    viene decrementato di uno e \func{semop} ritorna un errore di
+    \macro{EINTR}.
+  \end{itemize*}    
+  Al processo chiamante è richiesto il privilegio di alterazione (scrittura)
+  sull'insieme di semafori.
+\end{basedescript}
 
+In caso di successo della funzione viene aggiornato di \var{sempid} per ogni
+semaforo modificato al valore del \acr{pid} del processo chiamante; inoltre
+vengono pure aggiornati al tempo corrente i campi \var{sem\_otime} e
+\var{sem\_ctime}.
+
+Dato che, come già accennato in precedenza, in caso di uscita inaspettata i
+semafori possono restare occupati, abbiamo visto come \func{semop} permetta di
+attivare un meccanismo di ripristino attraverso l'uso del flag
+\macro{SEM\_UNDO}. Il meccanismo è implementato tramite una apposita struttura
+\var{sem\_undo}, associata ad ogni processo per ciascun semaforo che esso ha
+modificato; all'uscita i semafori modificati vengono ripristinati, e le
+strutture disallocate.  Per mantenere coerente il comportamento queste
+strutture non vengono ereditate attraverso una \func{fork} (altrimenti si
+avrebbe un doppio ripristino), mentre vengono passate nell'esecuzione di una
+\func{exec} (altrimenti non si avrebbe ripristino).
+
+Resta comunque insoluto il problema di fondo di questo meccanismo, che non si
+adatta al concetto di operazioni atomiche su un semaforo, dato che le
+richieste di ripristino si accumulano attraverso diverse chiamate a
+\func{semop}, cosa succede se all'uscita del processo?  Si deve porre il
+processo in stato di \textit{sleep} o andare avanti come se fosse stato
+impostato \macro{IPC\_NOWAIT}. La scelta del kernel è quella di effettuare le
+operazioni che non prevedono un blocco del processo ed ignorare
+silenziosamente le altre. Questo comporta che un comportamento senza problemi
+può essere garantito solo per i semafori privati.
 
 
 \subsection{Memoria condivisa}