Aggiunti alcuni header alla lista e quattro chiacchiere sulle alternative
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index b0eb27ee76a651086eae29ee98b0fc9cc9efe8dc..d8ffa5f83268604dfaa2149b95c72f096f44a664 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -2524,12 +2524,6 @@ invece:
   al segmento viene inizializzato a zero.
 \end{itemize*}
 
-La struttura di come vengono gestiti i segmenti di memoria condivisa nel
-kernel è illustrata in . 
-
-
-
-
 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
@@ -2613,12 +2607,12 @@ attraverso l'argomento \param{cmd}, i valori possibili sono i seguenti:
   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 solo in Linux. 
+gli ultimi due sono delle estensioni previste da Linux. 
 
-Per utilizzare i segmenti di memoria condivisa si usano due funzioni, la prima
-di queste è \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 è:
+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}
@@ -2635,8 +2629,6 @@ il suo prototipo 
     \item[\macro{EINVAL}] Si è specificato un identificatore invalido per
       \param{shmid}, o un indirizzo non allineato sul confine di una pagina
       per \param{shmaddr}.
-    \item[\macro{EIDRM}] Si è richiesto un segmento marcato per la
-      cancellazione.
     \end{errlist}
     ed inoltre \macro{ENOMEM}.}
 \end{functions}
@@ -2645,8 +2637,9 @@ 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 al proposito quanto illustrato in \secref{sec:proc_mem_layout}).
-
+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
@@ -2656,7 +2649,6 @@ ricordi al proposito quanto illustrato in \secref{sec:proc_mem_layout}).
   \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
@@ -2665,23 +2657,54 @@ L'argomento \param{shmaddr} specifica a quale indirizzo\footnote{Lo standard
   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 aggangia il segmento all'indirizzo specificato da
+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
-
-
-
-
-La seconda funzione è \func{shmdt}, che consente di sganciare un segmento di
-memoria condivisa dal processo chiamante quando questo non è più necessario,
-il suo prototipo è:
+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}
@@ -2689,27 +2712,69 @@ il suo prototipo 
   \funcdecl{int shmdt(const void *shmaddr)}
   Sgancia dal processo un segmento di memoria condivisa.
   
-  \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
+  \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{nel capitolo 14.}
-Stevens effettua una accurata analisi (i cui concetti sono già stati accennati
-in precedenza) ed elenca alcune possibili alternative, che vogliamo riprendere
-in questa sezione.
+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}, 
+Abbiamo esaminato il \textit{file locking} in \secref{sec:file_locking},