%% License".
%%
-\chapter{La comunicazione fra processi}
+\chapter{L'intercomunicazione fra processi}
\label{cha:IPC}
implementati con un ulteriore livello sopra i meccanismi elementari.
-\section{La comunicazione fra processi tradizionale}
+\section{L'intercomunicazione fra processi tradizionale}
\label{sec:ipc_unix}
Il primo meccanismo di comunicazione fra processi introdotto nei sistemi Unix,
capi della pipe, associati a ciascun file descriptor, con le frecce che
indicano la direzione del flusso dei dati.
-\begin{figure}[htb]
+\begin{figure}[!htb]
\centering
\includegraphics[height=5cm]{img/pipe}
\caption{Schema della struttura di una pipe.}
fig.~\ref{fig:ipc_pipe_fork}). In questo modo se uno dei processi scrive su un
capo della pipe, l'altro può leggere.
-\begin{figure}[htb]
+\begin{figure}[!htb]
\centering
\includegraphics[height=5cm]{img/pipefork}
\caption{Schema dei collegamenti ad una pipe, condivisi fra processo padre e
pipe il cui capo in scrittura è stato chiuso, si avrà la ricezione di un EOF
(vale a dire che la funzione \func{read} ritornerà restituendo 0). Se invece
si esegue una scrittura su una pipe il cui capo in lettura non è aperto il
-processo riceverà il segnale \const{SIGPIPE}, e la funzione di scrittura
+processo riceverà il segnale \signal{SIGPIPE}, e la funzione di scrittura
restituirà un errore di \errcode{EPIPE} (al ritorno del gestore, o qualora il
segnale sia ignorato o bloccato).
secondo, secondo lo schema mostrato in fig.~\ref{fig:ipc_pipe_use}, in cui la
direzione del flusso dei dati è data dalle frecce continue.
-\begin{figure}[htb]
+\begin{figure}[!htb]
\centering
\includegraphics[height=5cm]{img/pipeuse}
\caption{Schema dell'uso di una pipe come mezzo di comunicazione fra
il cui codice completo è disponibile nel file \file{BarCodePage.c} che si
trova nella directory dei sorgenti.
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/BarCodePage.c}
\end{minipage}
\normalsize
risultato dell'elaborazione del precedente, benché quest'ultimo venga invocato
dopo.
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/BarCode.c}
\end{minipage}
\normalsize
richieste al server su una fifo nota mentre le risposte vengono reinviate dal
server a ciascuno di essi su una fifo temporanea creata per l'occasione.
-\begin{figure}[htb]
+\begin{figure}[!htb]
\centering
\includegraphics[height=9cm]{img/fifoserver}
\caption{Schema dell'utilizzo delle fifo nella realizzazione di una
diverso da quelli preimpostati. Il codice completo è nel file
\file{FortuneServer.c}.
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/FortuneServer.c}
\end{minipage}
\normalsize
principale del programma e le definizioni delle variabili. Il codice completo
è nel file \file{FortuneClient.c} dei sorgenti allegati.
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/FortuneClient.c}
\end{minipage}
\normalsize
che esamina questa architettura in \cite{APUE}, nota come sia impossibile
per il server sapere se un client è andato in crash, con la possibilità di
far restare le fifo temporanee sul filesystem, di come sia necessario
- intercettare \const{SIGPIPE} dato che un client può terminare dopo aver
+ intercettare \signal{SIGPIPE} dato che un client può terminare dopo aver
fatto una richiesta, ma prima che la risposta sia inviata (cosa che nel
nostro esempio non è stata fatta).}; in generale infatti l'interfaccia delle
fifo non è adatta a risolvere questo tipo di problemi, che possono essere
questa funzionalità in sez.~\ref{sec:sock_fd_passing}).
-\section{Il sistema di comunicazione fra processi di System V}
+\section{L'intercomunicazione fra processi di System V}
\label{sec:ipc_sysv}
Benché le pipe e le fifo siano ancora ampiamente usate, esse scontano il
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\textwidth}
\includestruct{listati/ipc_perm.h}
\end{minipage}
\normalsize
effettivamente esistente e di un numero di progetto \param{proj\_id)}, che di
norma viene specificato come carattere, dato che ne vengono utilizzati solo
gli 8 bit meno significativi.\footnote{nelle libc4 e libc5, come avviene in
- SunOS, l'argomento \param{proj\_id} è dichiarato tipo \ctyp{char}, le
- \acr{glibc} usano il prototipo specificato da XPG4, ma vengono lo stesso
+ SunOS, l'argomento \param{proj\_id} è dichiarato tipo \ctyp{char}, la
+ \acr{glibc} usa il prototipo specificato da XPG4, ma vengono lo stesso
utilizzati gli 8 bit meno significativi.}
Il problema è che anche così non c'è la sicurezza che il valore della chiave
valore è 32768.} si evita così il riutilizzo degli stessi numeri, e si fa
sì che l'identificatore assuma tutti i valori possibili.
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/IPCTestId.c}
\end{minipage}
\normalsize
\procrelfile{/proc/sys/kernel}{msgmnb} e
\procrelfile{/proc/sys/kernel}{msgmni} di \file{/proc/sys/kernel/}.
-\begin{figure}[htb]
+\begin{figure}[!htb]
\centering \includegraphics[width=13cm]{img/mqstruct}
\caption{Schema della struttura di una coda messaggi.}
\label{fig:ipc_mq_schema}
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\textwidth}
\includestruct{listati/msqid_ds.h}
\end{minipage}
\normalsize
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\textwidth}
\includestruct{listati/msgbuf.h}
\end{minipage}
\normalsize
useremo una sola coda di messaggi, usando il tipo di messaggio per comunicare
in maniera indipendente con client diversi.
-\begin{figure}[!bht]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15.6cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/MQFortuneServer.c}
\end{minipage}
\normalsize
gestore \code{HandSIGTERM}, che semplicemente si limita a cancellare la coda
(\texttt{\small 46}) ed ad uscire (\texttt{\small 47}).
-\begin{figure}[!bht]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15.6cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/MQFortuneClient.c}
\end{minipage}
\normalsize
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\textwidth}
\includestruct{listati/semid_ds.h}
\end{minipage}
\normalsize
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\textwidth}
\includestruct{listati/sem.h}
\end{minipage}
\normalsize
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\textwidth}
\includestruct{listati/semun.h}
\end{minipage}
\normalsize
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\textwidth}
\includestruct{listati/sembuf.h}
\end{minipage}
\normalsize
a queste strutture restano per compatibilità.\footnote{in particolare con le
vecchie versioni delle librerie del C, come le libc5.}
-\begin{figure}[htb]
+\begin{figure}[!htb]
\centering \includegraphics[width=13cm]{img/semtruct}
\caption{Schema della struttura di un insieme di semafori.}
\label{fig:ipc_sem_schema}
valore unitario per segnalare la disponibilità della risorsa, ed un valore
nullo per segnalarne l'indisponibilità.
-\begin{figure}[!bht]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/Mutex.c}
\end{minipage}
\normalsize
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\textwidth}
\includestruct{listati/shmid_ds.h}
\end{minipage}
\normalsize
Si tenga presente infine 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}
+\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}
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
+ \acr{libc4} e le \acr{libc5}, con il passaggio alla \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 è \val{NULL} è il sistema a scegliere opportunamente un'area di
lettura (si ricordi che anche le pagine di memoria hanno dei permessi), in tal
caso un tentativo di scrivere sul segmento comporterà una
\itindex{segment~violation} violazione di accesso con l'emissione di un
-segnale di \const{SIGSEGV}. Il comportamento usuale di \func{shmat} è quello
+segnale di \signal{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.
inoltre la regione di indirizzi usata per il segmento di memoria condivisa
viene tolta dallo spazio di indirizzi del processo.
-\begin{figure}[!bht]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15.6cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/SharedMem.c}
\end{minipage}
\normalsize
In fig.~\ref{fig:ipc_dirmonitor_main} si è riportata la sezione principale del
corpo del programma server, insieme alle definizioni delle altre funzioni
-usate nel programma e delle variabili globali, omettendo tutto quello che
-riguarda la gestione delle opzioni e la stampa delle istruzioni di uso a
-video; al solito il codice completo si trova con i sorgenti allegati nel file
-\file{DirMonitor.c}.
+usate nel programma e delle \index{variabili!globali} variabili globali,
+omettendo tutto quello che riguarda la gestione delle opzioni e la stampa
+delle istruzioni di uso a video; al solito il codice completo si trova con i
+sorgenti allegati nel file \file{DirMonitor.c}.
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15.6cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/DirMonitor.c}
\end{minipage}
\normalsize
\label{fig:ipc_dirmonitor_main}
\end{figure}
-Il programma usa delle variabili globali (\texttt{\small 2--14}) per mantenere
-i valori relativi agli oggetti usati per la comunicazione inter-processo; si è
-definita inoltre una apposita struttura \struct{DirProp} che contiene i dati
-relativi alle proprietà che si vogliono mantenere nella memoria condivisa, per
-l'accesso da parte dei client.
+Il programma usa delle \index{variabili!globali} variabili globali
+(\texttt{\small 2--14}) per mantenere i valori relativi agli oggetti usati per
+la comunicazione inter-processo; si è definita inoltre una apposita struttura
+\struct{DirProp} che contiene i dati relativi alle proprietà che si vogliono
+mantenere nella memoria condivisa, per l'accesso da parte dei client.
Il programma, dopo la sezione, omessa, relativa alla gestione delle opzioni da
riga di comando (che si limitano alla eventuale stampa di un messaggio di
di interfaccia già descritte in sez.~\ref{sec:ipc_sysv_sem}, anche un mutex,
che utilizzeremo per regolare l'accesso alla memoria condivisa.
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15.6cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/ComputeValues.c}
\end{minipage}
\normalsize
Come si vede la funzione (\texttt{\small 2--16}) è molto semplice e si limita
a chiamare (\texttt{\small 5}) la funzione \func{stat} sul file indicato da
ciascuna voce, per ottenerne i dati, che poi utilizza per incrementare i vari
-contatori nella memoria condivisa, cui accede grazie alla variabile globale
-\var{shmptr}.
+contatori nella memoria condivisa, cui accede grazie alla
+\index{variabili!globali} variabile globale \var{shmptr}.
Dato che la funzione è chiamata da \func{DirScan}, si è all'interno del ciclo
principale del programma, con un mutex acquisito, perciò non è necessario
memoria condivisa usando \func{ShmRemove}. Infine (\texttt{\small 21})
rimuove il mutex con \func{MutexRemove} ed esce (\texttt{\small 22}).
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15.6 cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/ReadMonitor.c}
\end{minipage}
\normalsize
%$
A questo punto possiamo far uscire il server inviandogli un segnale di
-\const{SIGTERM} con il comando \code{killall dirmonitor}, a questo punto
+\signal{SIGTERM} con il comando \code{killall dirmonitor}, a questo punto
ripetendo la lettura, otterremo un errore:
\begin{Verbatim}
[piccardi@gont sources]$ ./readmon
%% condivisa; uno schema semplificato della struttura è illustrato in
%% fig.~\ref{fig:ipc_shm_struct}.
-%% \begin{figure}[htb]
+%% \begin{figure}[!htb]
%% \centering
%% \includegraphics[width=10cm]{img/shmstruct}
%% \caption{Schema dell'implementazione dei segmenti di memoria condivisa in
cui alla fine l'uso delle code di messaggi classiche è relativamente poco
diffuso.
+% TODO: trattare qui, se non ssis trova posto migliore, copy_from_process e
+% copy_to_process, introdotte con il kernel 3.2. Vedi
+% http://lwn.net/Articles/405346/ e
+% http://ozlabs.org/~cyeoh/cma/process_vm_readv.txt
+
+
\subsection{I \textsl{file di lock}}
\label{sec:ipc_file_lock}
9}) nella modalità descritta, mentre la seconda (\texttt{\small 11--17}) lo
cancella con \func{unlink}.
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15.6cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/LockFile.c}
\end{minipage}
\normalsize
dovendo fare ricorso a delle operazioni sul filesystem, esso è in genere
leggermente più lento.
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15.6cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/MutexLocking.c}
\end{minipage}
\normalsize
% TODO fare esempio di mmap anonima
-\section{Il sistema di comunicazione fra processi di POSIX}
+\section{L'intercomunicazione fra processi di POSIX}
\label{sec:ipc_posix}
Per superare i numerosi problemi del \textit{SysV IPC}, evidenziati per i suoi
Oggi Linux supporta tutti gli oggetti definito nello standard POSIX per l'IPC,
ma a lungo non è stato così; la memoria condivisa è presente a partire dal
-kernel 2.4.x, i semafori sono forniti dalle \acr{glibc} nella sezione che
+kernel 2.4.x, i semafori sono forniti dalla \acr{glibc} nella sezione che
implementa i \itindex{thread} \textit{thread} POSIX di nuova generazione che
richiedono il kernel 2.6, le code di messaggi sono supportate a partire dal
kernel 2.6.6.
programmi che usano le code di messaggi cioè devono essere compilati
aggiungendo l'opzione \code{-lmqueue} al comando \cmd{gcc}; in
corrispondenza all'inclusione del supporto nel kernel ufficiale anche
- \file{libmqueue} è stata inserita nelle \acr{glibc}, a partire dalla
+ \file{libmqueue} è stata inserita nella \acr{glibc}, a partire dalla
versione 2.3.4 delle medesime.} che contiene le funzioni dell'interfaccia
POSIX.\footnote{in realtà l'implementazione è realizzata tramite delle
opportune chiamate ad \func{ioctl} sui file del filesystem speciale su cui
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\textwidth}
\includestruct{listati/mq_attr.h}
\end{minipage}
\normalsize
suoi contenuti in memoria, che viene attivato abilitando l'opzione
\texttt{CONFIG\_TMPFS} in fase di compilazione del kernel.
-Per potere utilizzare l'interfaccia POSIX per la memoria condivisa le
-\acr{glibc}\footnote{le funzioni sono state introdotte con le glibc-2.2.}
-richiedono di compilare i programmi con l'opzione \code{-lrt}; inoltre è
+Per potere utilizzare l'interfaccia POSIX per la memoria condivisa la
+\acr{glibc}\footnote{le funzioni sono state introdotte con la versione 2.2.}
+richiede di compilare i programmi con l'opzione \code{-lrt}; inoltre è
necessario che in \file{/dev/shm} sia montato un filesystem \texttt{tmpfs};
questo di norma viene fatto aggiungendo una riga del tipo di:
\begin{verbatim}
usato \const{O\_CREAT}, in quest'ultimo caso comunque si otterrà un file
descriptor che fa riferimento ad un segmento distinto da eventuali precedenti.
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15.6cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/MemShared.c}
\end{minipage}
\normalsize
erano visibili solo all'interno dei \itindex{thread} \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} delle \acr{glibc}.\footnote{quelle che si
+estensioni \textit{real-time} della \acr{glibc}.\footnote{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 SysV IPC (mantenendo così tutti i problemi sottolineati in
sincronizzazione completamente nuovo, basato sui cosiddetti
\textit{futex},\footnote{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 delle
+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 quella
che viene chiamata \textit{New Posix Thread Library}, sono state implementate
anche tutte le funzioni dell'interfaccia dei semafori POSIX.
\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 \itindex{thread} \textit{thread}, si
-dovrà usare cioè una variabile globale o una variabile allocata dinamicamente
-nello \itindex{heap} \textit{heap}.
+dovrà usare cioè una \index{variabili!globali} variabile globale o una
+variabile allocata dinamicamente nello \itindex{heap} \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
monitorare il contenuto di un segmento di memoria condivisa e modificarne il
contenuto.
-\begin{figure}[!h]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/message_getter.c}
\end{minipage}
\normalsize
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.
+\index{variabili!globali} 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
semaforo ad inizio del ciclo; seguito (\texttt{\small 35--36}) dal tempo
corrente.
-\begin{figure}[!h]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/HandSigInt.c}
\end{minipage}
\normalsize
Per uscire in maniera corretta dal programma sarà necessario interromperlo con
il break da tastiera (\texttt{C-c}), che corrisponde all'invio del segnale
-\const{SIGINT}, per il quale si è installato (\texttt{\small 10}) una
+\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}[!h]
+\begin{figure}[!htbp]
\footnotesize \centering
- \begin{minipage}[c]{15cm}
+ \begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/message_setter.c}
\end{minipage}
\normalsize