Aggiunti alcuni header alla lista e quattro chiacchiere sulle alternative
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index f06dfbf9efcd56baf74b9feb0c9dcb443b945e73..d8ffa5f83268604dfaa2149b95c72f096f44a664 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1242,7 +1242,7 @@ una 
     di messaggi specificando una chiave che non esiste e \macro{IPC\_CREAT}
     non era specificato.
   \item[\macro{ENOSPC}] Si è cercato di creare una coda di messaggi quando è
-    stato il limite massimo del sistema.
+    stato superato il limite massimo di code (\macro{MSGMNI}).
   \end{errlist}
   ed inoltre \macro{ENOMEM}.
 }
@@ -1901,8 +1901,21 @@ permette di creare o ottenere l'identificatore di un insieme di semafori 
   Restituisce l'identificatore di un insieme di semafori.
   
   \bodydesc{La funzione restituisce l'identificatore (un intero positivo) o -1
-    in caso di errore, nel qual caso \var{errno} assumerà gli stessi valori
-    visti per \func{msgget}.}
+    in caso di errore, nel qual caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\macro{ENOSPC}] Si è cercato di creare una insieme di semafori
+      quando è stato superato o il limite per il numero totale di semafori
+      (\macro{SEMMNS}) o quello per il numero totale degli insiemi
+      (\macro{SEMMNI}) nel sistema.
+    \item[\macro{EINVAL}] L'argomento \param{nsems} è minore di zero o
+      maggiore del limite sul numero di semafori per ciascun insieme
+      (\macro{SEMMSL}), o se l'insieme già esiste, maggiore del numero di
+      semafori che contiene.
+    \item[\macro{ENOMEM}] Il sistema non ha abbastanza memoria per poter
+      contenere le strutture per un nuovo insieme di semafori.
+    \end{errlist}
+    ed inoltre \macro{EACCES}, \macro{ENOENT}, \macro{EEXIST}, \macro{EIDRM},
+    con lo stesso significato che hanno per \func{msgget}.}
 \end{functions}
 
 La funzione è del tutto analoga a \func{msgget}, solo che in questo caso
@@ -1966,7 +1979,7 @@ semaforo), per quanto riguarda gli altri campi invece:
 \item il campo \var{sem\_nsems}, che esprime il numero di semafori
   nell'insieme, viene inizializzato al valore di \param{nsems}.
 \item il campo \var{sem\_ctime}, che esprime il tempo di creazione
-  dell'insieme, viene inizializzato al tempo corrente
+  dell'insieme, viene inizializzato al tempo corrente.
 \item il campo \var{sem\_otime}, che esprime il tempo dell'ultima operazione
   effettuata, viene inizializzato a zero.
 \end{itemize*}
@@ -1980,9 +1993,9 @@ Ciascun semaforo dell'insieme 
   dinamicamente. La si è utilizzata a scopo di esempio, perché indica tutti i
   valori associati ad un semaforo, restituiti dalle funzioni di controllo, e
   citati dalle pagine di manuale.} è riportata in \figref{fig:ipc_sem}. Questa
-struttura, come le altre, non è accessibile in user space, ma i valori in essa
-specificati possono essere letti in maniera indiretta, attraverso l'uso delle
-funzioni di controllo. 
+struttura, non è accessibile in user space, ma i valori in essa specificati
+possono essere letti in maniera indiretta, attraverso l'uso delle funzioni di
+controllo.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -2006,7 +2019,7 @@ indicano rispettivamente:
 \begin{description*}
 \item[\var{semval}] il valore numerico del semaforo.
 \item[\var{sempid}] il \acr{pid} dell'ultimo processo che ha eseguito una
-  operazione sul semaforo
+  operazione sul semaforo.
 \item[\var{semncnt}] il numero di processi in attesa che esso venga
   incrementato.
 \item[\var{semzcnt}] il numero di processi in attesa che esso si annulli.
@@ -2038,8 +2051,6 @@ indicano rispettivamente:
   \label{tab:ipc_sem_limits}
 \end{table}
 
-
-
 Come per le code di messaggi anche per gli insiemi di semafori esistono una
 serie di limiti, i cui valori sono associati ad altrettante costanti, che si
 sono riportate in \tabref{tab:ipc_sem_limits}. Alcuni di questi limiti sono al
@@ -2258,7 +2269,6 @@ opportuna struttura \var{sembuf} (la cui definizione 
 \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
@@ -2398,26 +2408,26 @@ l'operazione;\footnote{attraverso il campo \var{semundo} di
 processo termina, la lista ad esso associata viene scandita e le operazioni
 applicate al semaforo.
 
-Siccome le richieste di ripristino si accumulano attraverso diverse chiamate a
-\func{semop} per semafori diversi, si pone il problema di come viene eseguito
-il ripristino all'uscita del processo, in particolare se questo può essere
-fatto atomicamente. Il punto è cosa succede quando una delle operazioni
-previste per il ripristino non può essere eseguita immediatamente perché ad
-esempio il semaforo è occupato; in tal caso infatti, se si pone il processo in
-stato di \textit{sleep} aspettando la disponibilità del semaforo (come faceva
-l'implementazione originaria) si perde l'atomicità dell'operazione. La scelta
-fatta dal kernel è pertanto quella di effettuare subito le operazioni che non
-prevedono un blocco del processo e di ignorare silenziosamente le altre;
-questo però comporta il fatto che il ripristino non è comunque garantito in
-tutte le occasioni.
+Siccome un processo può accumulare delle richieste di ripristino per semafori
+differenti chiamate attraverso diverse chiamate a \func{semop}, si pone il
+problema di come eseguire il ripristino dei semafori all'uscita del processo,
+ed in particolare se questo può essere fatto atomicamente. Il punto è cosa
+succede quando una delle operazioni previste per il ripristino non può essere
+eseguita immediatamente perché ad esempio il semaforo è occupato; in tal caso
+infatti, se si pone il processo in stato di \textit{sleep} aspettando la
+disponibilità del semaforo (come faceva l'implementazione originaria) si perde
+l'atomicità dell'operazione. La scelta fatta dal kernel è pertanto quella di
+effettuare subito le operazioni che non prevedono un blocco del processo e di
+ignorare silenziosamente le altre; questo però comporta il fatto che il
+ripristino non è comunque garantito in tutte le occasioni.
 
 
 \subsection{Memoria condivisa}
 \label{sec:ipc_sysv_shm}
 
-Il terzo oggetto introdotto dal \textit{System V IPC} è quello della memoria
-condivisa. La funzione che permette di ottenerne uno è \func{shmget} ed il suo
-prototipo è:
+Il terzo oggetto introdotto dal \textit{System V IPC} è quello dei segmenti di
+memoria condivisa. La funzione che permette di ottenerne uno è \func{shmget},
+ed il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
@@ -2428,13 +2438,350 @@ prototipo 
   Restituisce l'identificatore di una memoria condivisa.
   
   \bodydesc{La funzione restituisce l'identificatore (un intero positivo) o -1
-    in caso di errore, nel qual caso \var{errno} assumerà gli stessi valori
-    visti per \func{msgget}.}
+    in caso di errore, nel qual caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\macro{ENOSPC}] Si è superato il limite (\macro{SHMMNI}) sul numero
+      di segmenti di memoria nel sistema, o cercato di allocare un segmento le
+      cui dimensioni fanno superare il limite di sistema (\macro{SHMALL}) per
+      la memoria ad essi riservata.
+    \item[\macro{EINVAL}] Si è richiesta una dimensione per un nuovo segmento
+      maggiore di \macro{SHMMAX} o minore di \macro{SHMMIN}, o se il segmento
+      già esiste \param{size} è maggiore delle sue dimensioni.
+    \item[\macro{ENOMEM}] Il sistema non ha abbastanza memoria per poter
+      contenere le strutture per un nuovo segmento di memoria condivisa.
+    \end{errlist}
+    ed inoltre \macro{EACCES}, \macro{ENOENT}, \macro{EEXIST}, \macro{EIDRM},
+    con lo stesso significato che hanno per \func{msgget}.}
 \end{functions}
 
 La funzione, come \func{semget}, è del tutto analoga a \func{msgget}, ed
-identico è l'uso degli argomenti \param{key} e \param{flag}. L'argomento
+identico è l'uso degli argomenti \param{key} e \param{flag} per cui non
+ripeteremo quanto detto al proposito in \secref{sec:ipc_sysv_mq}. L'argomento
+\param{size} specifica invece la dimensione, in byte, del segmento, che viene
+comunque arrotondata al multiplo superiore di \macro{PAGE\_SIZE}.
+
+La memoria condivisa è la forma più veloce di comunicazione fra due processi,
+in quanto permette agli stessi di vedere nel loro spazio di indirizzi una
+stessa sezione di memoria.  Pertanto non è necessaria nessuna operazione di
+copia per trasmettere i dati da un processo all'altro, in quanto ciascuno può
+accedervi direttamente con le normali operazioni di lettura e scrittura dei
+dati in memoria.
+
+Ovviamente tutto questo ha un prezzo, ed il problema fondamentale della
+memoria condivisa è la sincronizzazione degli accessi. È evidente infatti che
+se un processo deve scambiare dei dati con un altro, si deve essere sicuri che
+quest'ultimo non acceda al segmento di memoria condivisa prima che il primo
+non abbia completato le operazioni di scrittura, inoltre nel corso di una
+lettura si deve essere sicuri che i dati restano coerenti e non vengono
+sovrascritti da un accesso in scrittura sullo stesso segmento da parte di un
+altro processo; per questo in genere la memoria condivisa viene sempre
+utilizzata in abbinamento ad un meccanismo di sincronizzazione, il che, di
+norma, significa insime a dei semafori.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}
+struct shmid_ds {
+     struct    ipc_perm shm_perm;  /* operation perms */
+     int  shm_segsz;               /* size of segment (bytes) */
+     time_t    shm_atime;          /* last attach time */
+     time_t    shm_dtime;          /* last detach time */
+     time_t    shm_ctime;          /* last change time */
+     unsigned short shm_cpid;      /* pid of creator */
+     unsigned short shm_lpid;      /* pid of last operator */
+     short     shm_nattch;         /* no. of current attaches */
+};
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \var{shmid\_ds}, associata a ciascun segmento di
+    memoria condivisa.}
+  \label{fig:ipc_shmid_ds}
+\end{figure}
+
+A ciascun segmento di memoria condivisa è associata una struttura
+\var{shmid\_ds}, riportata in \figref{fig:ipc_shmid_ds}.  Come nel caso delle
+code di messaggi quando si crea un nuovo segmento di memoria condivisa con
+\func{shmget} questa struttura viene inizializzata, in particolare il campo
+\var{shm\_perm} viene inizializzato come illustrato in
+\secref{sec:ipc_sysv_access_control}, e valgono le considerazioni ivi fatte
+relativamente ai permessi di accesso; per quanto riguarda gli altri campi
+invece:
+\begin{itemize*}
+\item il campo \var{shm\_segsz}, che esprime la dimensione del segmento, viene
+  inizializzato al valore di \param{size}.
+\item il campo \var{shm\_ctime}, che esprime il tempo di creazione del
+  segmento, viene inizializzato al tempo corrente.
+\item i campi \var{shm\_atime} e \var{shm\_atime}, che esprimno
+  rispettivamente il tempo dell'ultima volta che il segmento è stato
+  agganciato o sganciato da un processo, vengono inizializzati a zero.
+\item il campo \var{shm\_lpid}, che esprime il \acr{pid} del processo che ha
+  eseguito l'ultima operazione, viene inizializzato a zero.
+\item il campo \var{shm\_cpid}, che esprime il \acr{pid} del processo che ha
+  creato il segmento, viene inizializzato al \acr{pid} del processo chiamante.
+\item il campo \var{shm\_nattac}, che esprime il numero di processi agganciati
+  al segmento viene inizializzato a zero.
+\end{itemize*}
+
+Come per le code di messaggi e gli insiemi di semafori, anche per i segmenti
+di memoria condivisa esistono una serie di limiti, i cui valori, riportati in
+\tabref{tab:ipc_shm_limits} sono associati ad altrettante costanti.  Alcuni di
+questi limiti sono al solito accessibili e modificabili attraverso
+\func{sysctl} o scrivendo direttamente nei rispettivi file di
+\file{/proc/sys/kernel/}.
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|c|r|c|p{7cm}|}
+    \hline
+    \textbf{Costante} & \textbf{Valore} & \textbf{File in \texttt{proc}}
+    & \textbf{Significato} \\
+    \hline
+    \hline
+    \macro{SHMALL}&0x200000&\file{shmall}& Numero massimo di pagine che 
+                                       possono essere usate per i segmenti di
+                                       memoria condivisa. \\
+    \macro{SHMMAX}&0x2000000&\file{shmmax}& Dimensione massima di un segmento 
+                                       di memoria condivisa.\\
+    \macro{SHMMNI}&4096&\file{msgmni}& Numero massimo di segmenti di memoria
+                                       condivisa presenti nel kernel.\\
+    \macro{SHMMIN}&   1& ---         & Dimensione minima di un segmento di
+                                       memoria condivisa. \\
+    \hline
+  \end{tabular}
+  \caption{Valori delle costanti associate ai limiti dei segmenti di memoria
+    condivisa, insieme al relativo file in \file{/proc/sys/kernel/} ed al
+    valore preimpostato presente nel sistema.} 
+  \label{tab:ipc_shm_limits}
+\end{table}
+
+Al solito la funzione che permette di effettuare le operazioni di controllo su
+un segmento di memoria condivisa è \func{shmctl}; il suo prototipo è:
+\begin{functions}
+  \headdecl{sys/ipc.h} 
+  \headdecl{sys/shm.h}
+  
+  \funcdecl{int shmctl(int shmid, int cmd, struct shmid\_ds *buf)}
+  
+  Esegue le operazioni di controllo su un segmento di memoria condivisa.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\macro{EACCES}] Si è richiesto \macro{IPC\_STAT} ma i permessi non
+      consentono l'accesso in lettura al segmento.
+    \item[\macro{EINVAL}] O \param{shmid} o \param{cmd} hanno valori non
+      validi.
+    \item[\macro{EIDRM}] L'argomento \param{shmid} fa riferimento ad un
+      segmento che è stato cancellato.
+    \item[\macro{EPERM}] Si è specificato un comando con \macro{IPC\_SET} o
+      \macro{IPC\_RMID} senza i permessi necessari.
+    \item[\macro{EOVERFLOW}] L'argomento \param{shmid} fa riferimento ad un
+      segmento che è stato cancellato.
+    \end{errlist}
+  ed inoltre \macro{EFAULT}.}
+\end{functions}
+
+Il comportamento della funzione dipende dal valore del comando passato
+attraverso l'argomento \param{cmd}, i valori possibili sono i seguenti:
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\macro{IPC\_STAT}] Legge le informazioni riguardo il segmento di memoria
+  condivisa nella struttura \var{shmid\_ds} puntata da \param{buf}. Occorre
+  avere il permesso di lettura sulla coda.
+\item[\macro{IPC\_RMID}] Marca il segmento di memoria condivisa per la
+  rimozione, questo verrà cancellato effettivamente solo quando l'ultimo
+  processo ad esso agganciato si sarà staccato. Questo comando può essere
+  eseguito solo da un processo con userid effettivo, corrispondente al
+  creatore o al proprietario della coda, o all'amministratore.
+\item[\macro{IPC\_SET}] Permette di modificare i permessi ed il proprietario
+  del segmento.  Per modificare i valori di \var{shm\_perm.mode},
+  \var{shm\_perm.uid} e \var{shm\_perm.gid} occorre essere il proprietario o
+  il creatore della coda, oppure l'amministratore. Compiuta l'operazione
+  aggiorna anche il valore del campo \var{shm\_ctime}.
+\item[\macro{SHM\_LOCK}] Abilita il \textit{memory locking}\index{memory
+    locking} (vedi \secref{sec:proc_mem_lock}) sul segmento di memoria
+  condivisa. Solo l'amministratore può utilizzare questo comando.
+\item[\macro{SHM\_UNLOCK}] Disabilita il \textit{memory locking}. Solo
+  l'amministratore può utilizzare questo comando.
+\end{basedescript}
+i primi tre comandi sono gli stessi già visti anche per le code ed i semafori,
+gli ultimi due sono delle estensioni previste da Linux. 
+
+Per utilizzare i segmenti di memoria condivisa l'interfaccia prevede due
+funzioni, la prima è \func{shmat}, che serve ad agganciare un segmento al
+processo chiamante, in modo che quest'ultimo possa vederlo nel suo spazio di
+indirizzi; il suo prototipo è:
+\begin{functions}
+  \headdecl{sys/types.h} 
+  \headdecl{sys/shm.h}
+  
+  \funcdecl{void *shmat(int shmid, const void *shmaddr, int shmflg)}
+  Aggancia al processo un segmento di memoria condivisa.
+  
+  \bodydesc{La funzione restituisce l'indirizzo del segmento in caso di
+    successo, e -1 in caso di errore, nel qual caso \var{errno} assumerà i
+    valori:
+    \begin{errlist}
+    \item[\macro{EACCES}] Il processo non ha i privilegi per accedere al
+      segmento nella modalità richiesta.
+    \item[\macro{EINVAL}] Si è specificato un identificatore invalido per
+      \param{shmid}, o un indirizzo non allineato sul confine di una pagina
+      per \param{shmaddr}.
+    \end{errlist}
+    ed inoltre \macro{ENOMEM}.}
+\end{functions}
+
+La funzione inserisce un segmento di memoria condivisa all'interno dello
+spazio di indirizzi del processo, in modo che questo possa accedervi
+direttamente, la situazione dopo l'esecuzione di \func{shmat} è illustrata in
+\figref{fig:ipc_shmem_layout} (per la comprensione del resto dello schema si
+ricordi quanto illustrato al proposito in \secref{sec:proc_mem_layout}). Si
+tenga presente che la funzione ha successo anche se il segmento è stato
+marcato per la cancellazione.
+
+\begin{figure}[htb]
+  \centering
+  \includegraphics[height=10cm]{img/sh_memory_layout}
+  \caption{Disposizione dei segmenti di memoria di un processo quando si è
+    agganciato un segmento di memoria condivisa.}
+  \label{fig:ipc_shmem_layout}
+\end{figure}
+
+L'argomento \param{shmaddr} specifica a quale indirizzo\footnote{Lo standard
+  SVID prevede che l'argomento \param{shmaddr} sia di tipo \ctyp{char *}, così
+  come il valore di ritorno della funzione. In Linux è stato così con le
+  \acr{libc4} e le \acr{libc5}, con il passaggio alle \acr{glibc} il tipo di
+  \param{shmaddr} è divenuto un \ctyp{const void *} e quello del valore di
+  ritorno un \ctyp{void *}.} deve essere associato il segmento, se il valore
+specificato è \macro{NULL} è il sistema a scegliere opportunamente un'area di
+memoria libera (questo è il modo più portabile e sicuro di usare la funzione).
+Altrimenti il kernel aggancia il segmento all'indirizzo specificato da
+\param{shmaddr}; questo però può avvenire solo se l'indirizzo coincide con il
+limite di una pagina, cioè se è un multiplo esatto del parametro di sistema
+\macro{SHMLBA}, che in Linux è sempre uguale \macro{PAGE\_SIZE}.
+
+L'argomento \param{shmflg} permette di cambiare il comportamento della
+funzione; esso va specificato come maschera binaria, i bit utilizzati sono
+solo due e sono identificati dalle costanti \macro{SHM\_RND} e
+\macro{SHM\_RDONLY}, che vanno combinate con un OR aritmetico.  Specificando
+\macro{SHM\_RND} si evita che \func{shmat} ritorni un errore quando
+\param{shmaddr} non è allineato ai confini di una pagina. Si può quindi usare
+un valore qualunque per \param{shmaddr}, e il segmento verrà comunque
+agganciato, ma al più vicino multiplo di \macro{SHMLBA} (il nome della
+costante sta infatti per \textit{rounded}, e serve per specificare un
+indirizzo come arrotondamento).
+
+Il secondo bit permette di agganciare il segmento in sola lettura (si ricordi
+che anche le pagine di memoria hanno dei permessi), in tal caso un tentativo
+di scrivere sul segmento comporterà una violazione di accesso con l'emissione
+di un segnale di \macro{SIGSEGV}. Il comportamento usuale di \func{shmat} è
+quello di agganciare il segmento con l'accesso in lettura e scrittura (ed il
+processo deve aver questi permessi in \var{shm\_perm}), non è prevista la
+possibilità di agganciare un segmento in sola scrittura.
+
+In caso di successo la funzione aggiorna anche i seguenti campi di
+\var{shmid\_ds}:
+\begin{itemize*}
+\item il tempo \var{shm\_atime} dell'ultima operazione di aggancio 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
+  aumentato di uno.
+\end{itemize*} 
+
+Come accennato in \secref{sec:proc_fork} un segmento di memoria condivisa
+agganciato ad un precesso viene ereditato da un figlio attraverso una
+\func{fork}, dato che quest'ultimo riceve una copia dello spazio degli
+indirizzi del padre. Invece, dato che attraverso una \func{exec} viene
+eseguito un diverso programma con uno spazio di indirizzi completamente
+diverso, tutti i segmenti agganciati al processo originario vengono
+automaticamente sganciati. Lo stesso avviene all'uscita del processo
+attraverso una \func{exit}.
+
+
+Una volta che un segmento di memoria condivisa non serve più si può sganciarlo
+esplicitamente dal processo usando la seconda funzione dell'interfaccia,
+\func{shmdt}, il cui  il suo prototipo è:
+\begin{functions}
+  \headdecl{sys/types.h} 
+  \headdecl{sys/shm.h}
+
+  \funcdecl{int shmdt(const void *shmaddr)}
+  Sgancia dal processo un segmento di memoria condivisa.
+  
+  \bodydesc{La funzione restituisce 0 in caso di succes so, e -1 in caso di
+    errore, la funzione fallisce solo quando non c'è un segmento agganciato
+    all'indirizzo \func{shmaddr}, con \var{errno} che assume il valore
+    \macro{EINVAL}.}
+\end{functions}
+
+La funzione sgancia dallo spazio degli indirizzi del processo un segmento di
+memoria condivisa; questo viene identificato con l'indirizzo \param{shmaddr}
+restituito dalla precedente chiamata a \func{shmat} con il quale era stato
+agganciato al processo.
+
+
+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 visto in \secref{sec:ipc_sysv_generic} il sistema di IPC di
+System V presenta numerosi problemi; in \cite{APUE}\footnote{in particolare
+  nel capitolo 14.}  Stevens effettua una accurata analisi (alcuni dei
+concetti sono già stati accennati in precedenza) ed elenca alcune possibili
+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 di IPC di
+System V; esse infatti nacquero principalmente come meccanismo di
+comunicazione bidirezionale quando ancora le pipe erano ancora unidirezionali;
+abbiamo visto però in \secref{sec:ipc_socketpair} che la funzione
+\func{socketpair} permette di fare la stessa cosa senza incorrere nelle
+complicazioni introdotte dal sistema di IPC di System V. 
+
+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 cose che sono
+impossibili da ottenere con le pipe e i socket di \func{socketpair}.
+
+È però possibile implementare un meccanismo analogo attraverso l'uso di
+memoria condivisa e di meccanismi di sincronizzazione, (un esempio di
+reimplementazione di code di messaggi usando il \textit{memory mapping} e i
+semafori si trova in \cite{UNP2}). pertanto non è
+
+
+\subsection{La sincronizzazione con il \textit{file locking}}
+\label{sec:ipc_file_lock}
+
+Abbiamo esaminato il \textit{file locking} in \secref{sec:file_locking},
+
+
+
+\subsection{Il \textit{memory mapping} anonimo}
+\label{sec:ipc_mmap_anonymous}
 
+Abbiamo visto in \secref{sec:file_memory_map} come sia possibile 
 
 
 \section{La comunicazione fra processi di POSIX}