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
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
\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}
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
\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
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
-
-
+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, tutti i segmenti eventualmente agganciati al
+processo vengono automaticamente sganciati. Lo stesso avviene all'uscita del
+processo attraverso una \func{exit}.
La seconda funzione è \func{shmdt}, che consente di sganciare un segmento di
\macro{EINVAL}.}
\end{functions}
+La funzione esegue lo sganciamento del segmento di memoria condivisa
+agganciato all'indirizzo \param{shmaddr}; quest'ultimo deve essere uguale
+all'indirizzo ottenuto da una precedente chiamata a \func{shmat}.
+
+
+
+
+
+
+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}