Correzioni varie al codice ed alle relative citazioni
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index ed2d49267e852aa29b90c8141c9bca17c9a69791..6ae11a30a8e157e0f0d181583034dcb47f7489c9 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -556,20 +556,127 @@ struttura sequenziale delle fifo, i client dovrebbero sapere, prima di
 leggerli, quando i dati inviati sono destinati a loro.
 
 Per risolvere questo problema, si può usare un'architettura come quella
-illustrata da Stevens in \cite{APUE}, in cui le risposte vengono inviate su
-fifo temporanee identificate dal \acr{pid} dei client, ma in ogni caso il
-sistema è macchinoso e continua ad avere vari inconvenienti\footnote{lo stesso
-  Stevens 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, come sia necessario intercettare \macro{SIGPIPE} dato che un
-  client può terminare dopo aver fatto una richiesta, ma prima che la risposta
-  sia inviata, e come occorra gestire il caso in cui non ci sono client attivi
-  (e la lettura dalla fifo nota restituisca al serve un end-of-file.}; in
-generale infatti l'interfaccia delle fifo non è adatta a risolvere questo tipo
-di problemi, che possono essere affrontati in maniera più semplice ed efficace
-o usando i \textit{socket}\index{socket} (che tratteremo in dettaglio a
-partire da \capref{cha:socket_intro}) o ricorrendo a meccanismi di
-comunicazione diversi, come quelli che esamineremo in seguito.
+illustrata in \figref{fig:ipc_fifo_server_arch} in cui i client inviano le
+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'occazione.
+
+\begin{figure}[htb]
+  \centering
+  \includegraphics[height=9cm]{img/fifoserver}
+  \caption{Schema dell'utilizzo delle fifo nella realizzazione di una
+  architettura di comunicazione client/server.}
+  \label{fig:ipc_fifo_server_arch}
+\end{figure}
+
+Come esempio di uso questa architettura e dell'uso delle fifo, abbiamo scritto
+un server di \textit{fortunes}, che restituisce, alle richieste di un client,
+un detto a caso estratto da un insieme di frasi; sia il numero delle frasi
+dell'insieme, che i file da cui esse vengono lette all'avvio, sono importabili
+da riga di comando. Il corpo principale del server è riportato in
+\figref{fig:ipc_fifo_server}, dove si è tralasciata la parte che tratta la
+gestione delle opzioni a riga di comando, che effettua il settaggio delle
+variabili \var{fortunefilename}, che indica il file da cui leggere le frasi,
+ed \var{n}, che indica il numero di frasi tenute in memoria, ad un valore
+diverso da quelli preimpostati. Il codice completo è nel file
+\file{FortuneServer.c}.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}{}
+int main(int argc, char *argv[])
+{
+    int i, n = 10;
+    char *fortunefilename = "/usr/share/games/fortunes/kids";
+    char *fifoname = "/tmp/fortune.fifo";
+    char **fortune;
+    char line[80];
+    int fifo_server, fifo_client;
+    int nread;
+    ...
+    if (n==0) usage();          /* if no pool depth exit printing usage info */
+    i = FortuneParse(fortunefilename, fortune, n);          /* parse phrases */
+    /* 
+     * Comunication section 
+     */
+    if (mkfifo(fifoname, 0622)) {  /* create well known fifo if does't exist */
+        if (errno!=EEXIST) {
+            perror("Cannot create well known fifo");
+            exit(-1);
+        }
+    }
+    while (1) {
+        fifo_server = open(fifoname, O_RDONLY);      /* open well known fifo */
+        if (fifo_server < 0) {
+            perror("Cannot open well known fifo");
+            exit(-1);
+        }
+        nread = read(fifo_server, line, 79);                 /* read request */
+        line[nread] = 0;
+        n = random() % i;                             /* select random value */
+        fifo_client = open(line, O_WRONLY);              /* open client fifo */
+        nread = write(fifo_client,                           /* write phrase */
+                      fortune[n], strlen(fortune[n])+1);
+        close(fifo_client);                         /* close well known fifo */
+        close(fifo_server);                             /* close client fifo */
+    }
+}
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{Sezione principale del codice del server di \textit{fortunes}
+    basato sulle fifo.}
+  \label{fig:ipc_fifo_server}
+\end{figure}
+
+Il server richiede (\texttt{\small 11}) che sia stata impostata una dimensione
+dell'insieme delle frasi non nulla, stampando, nel caso ciò non avvenga, un
+messaggio apposito ed uscendo. Poi (\texttt{\small 12}) effettua la chiamata
+alla funzione \code{FortuneParse} che legge dal file specificato in
+\var{fortunefilename} le prime \var{n} frasi e le memorizza nel vettore di
+puntatori \var{fortune}. Il codice della funzione non è riportato, in quanto
+non direttamente attinente allo scopo dell'esempio, lo si può trovare nel file
+\file{FortuneParse.c} allegato coi sorgenti degli esempi.
+
+Il passo successivo \texttt{\small 16--21}) è quello di creare, se non esiste
+già, la fifo nota sulla quale il server ascolterà le richieste, qualora si
+riscontri un errore il server uscirà (escludendo ovviamente il caso in cui la
+funzione \func{mkfifo} fallisce per la precedente esistenza della fifo. 
+
+Fatto questo si entra nel ciclo principale del programma \texttt{\small
+  22--36}), che viene eseguito indefinitamente (l'uscita del server deve
+essere effettuata tramite segnale), e che provvede a fornire le risposte ai
+client. Il server è progettato per accettare le richieste dai client che
+devono scrivere il nome della fifo sulla quale vogliono ricevere la risposta
+sulla fifo su cui il server è in ascolto.
+
+Il primo passo è aprire in lettura la fifo (\texttt{\small 23}), se nessun
+client ha effettuato una richiesta la fifo non ha capi aperti in scrittura, e
+pertanto il server si bloccherà. Una volta che un client ha aperto la fifo in
+scrittura il server si sbloccherà ed effetturà la lettura (\texttt{\small 28})
+della richiesta del client (nel caso limitata a 79 byte).
+
+Dopo di che verrà calcolato (\texttt{\small 30}) un numero casuale nel range
+delle frasi disponibili nella nostra lista, e verrà aperta (\texttt{\small
+  31}) la fifo sulla quale il client vuole ricevere la risposta, che sarà poi
+scritta (\texttt{\small 32}). Dopo di che \texttt{\small 34--35}) entrambe le
+fifo verranno chiuse.
+
+
+Benché il nostro sistema client-server funzioni, la sua struttura è piuttosto
+complessa e continua ad avere vari inconvenienti\footnote{lo stesso Stevens,
+  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, come sia necessario
+  intercettare \macro{SIGPIPE} dato che un client può terminare dopo aver
+  fatto una richiesta, ma prima che la risposta sia inviata, e come occorra
+  gestire il caso in cui non ci sono client attivi (e la lettura dalla fifo
+  nota restituisca al serve un end-of-file.}; in generale infatti
+l'interfaccia delle fifo non è adatta a risolvere questo tipo di problemi, che
+possono essere affrontati in maniera più semplice ed efficace o usando i
+\textit{socket}\index{socket} (che tratteremo in dettaglio a partire da
+\capref{cha:socket_intro}) o ricorrendo a meccanismi di comunicazione diversi,
+come quelli che esamineremo in seguito.
 
 
 
@@ -813,13 +920,14 @@ assumere tutti i valori possibili, rendendo molto pi
 un identificatore può venire riutilizzato.
 
 Il sistema dispone sempre di un numero fisso di oggetti di IPC,\footnote{fino
-  al kernel 2.2.x questo numero, ed altri limiti relativi al \textit{System V
-    IPC}, potevano essere cambiati solo con una ricompilazione del kernel,
-  andando a modificare le costanti definite nei relativi haeder file.  A
-  partire dal kernel 2.4.x è possibile cambiare questi valori a sistema attivo
-  scrivendo sui file \file{shmmni}, \file{msgmni} e \file{sem} di
-  \file{/proc/sys/kernel} o con \texttt{syscntl}.} e per ciascuno di essi
-viene mantenuto in \var{seq} un numero di sequenza progressivo che viene
+  al kernel 2.2.x questi valori, definiti dalle costanti \macro{MSGMNI},
+  \macro{SEMMNI} e \macro{SHMMNI}, potevano essere cambiati (come tutti gli
+  altri limiti relativi al \textit{System V IPC}) solo con una ricompilazione
+  del kernel, andando a modificarne la definizione nei relativi haeder file.
+  A partire dal kernel 2.4.x è possibile cambiare questi valori a sistema
+  attivo scrivendo sui file \file{shmmni}, \file{msgmni} e \file{sem} di
+  \file{/proc/sys/kernel} o con l'uso di \texttt{syscntl}.} e per ciascuno di
+essi viene mantenuto in \var{seq} un numero di sequenza progressivo che viene
 incrementato di uno ogni volta che l'oggetto viene cancellato. Quando
 l'oggetto viene creato usando uno spazio che era già stato utilizzato in
 precedenza per restituire l'identificatore al numero di oggetti presenti viene
@@ -827,7 +935,7 @@ sommato il valore di \var{seq} moltiplicato per il numero massimo di oggetti
 di quel tipo,\footnote{questo vale fino ai kernel della serie 2.2.x, dalla
   serie 2.4.x viene usato lo stesso fattore per tutti gli oggetti, esso è dato
   dalla costante \macro{IPCMNI}, definita in \file{include/linux/ipc.h}, che
-  indica il limite massimo per il numero di oggetti di IPC, il cui valore è
+  indica il limite massimo per il numero di oggetti di IPC, ed il cui valore è
   32768.}  si evita così il riutilizzo degli stessi numeri, e si fa sì che
 l'identificatore assuma tutti i valori possibili.