Correzioni varie e aggiunte sulle fifo
authorSimone Piccardi <piccardi@gnulinux.it>
Tue, 9 Jul 2002 22:20:26 +0000 (22:20 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Tue, 9 Jul 2002 22:20:26 +0000 (22:20 +0000)
fileadv.tex
ipc.tex
network.tex
prochand.tex

index 744237990b07fc99dc9948e48d0e189b80d4f2bb..b376483c6c301882c1bb1698522287ff365fa29e 100644 (file)
@@ -28,7 +28,6 @@ I/O possono bloccarsi indefinitamente.\footnote{si ricordi per
 esempio le operazioni di lettura possono bloccarsi quando non ci sono dati
 disponibili sul descrittore su cui si sta operando.
 
 esempio le operazioni di lettura possono bloccarsi quando non ci sono dati
 disponibili sul descrittore su cui si sta operando.
 
-
 Questo comportamento causa uno dei problemi più comuni che ci si trova ad
 affrontare nelle operazioni di I/O, che è quello che si verifica quando si
 devono eseguire operazioni che possono bloccarsi su più file descriptor:
 Questo comportamento causa uno dei problemi più comuni che ci si trova ad
 affrontare nelle operazioni di I/O, che è quello che si verifica quando si
 devono eseguire operazioni che possono bloccarsi su più file descriptor:
@@ -59,7 +58,7 @@ bloccante.
 
 Per superare il problema di dover usare il \textit{polling} controllare la
 disponibilità di accesso ad un file aperto in modalità non bloccante, sia BSD
 
 Per superare il problema di dover usare il \textit{polling} controllare la
 disponibilità di accesso ad un file aperto in modalità non bloccante, sia BSD
-che SysV hanno introdotto delle nuove funzioni in grado di sospendere
+che System V hanno introdotto delle nuove funzioni in grado di sospendere
 l'esecuzione di un processo fino a che l'accesso diventi possibile; il primo
 ad introdurre questa nuova interfaccia, chiamata usualmente \textit{I/O
   multiplexing}, è stato BSD, con l'introduzione della funzione \func{select},
 l'esecuzione di un processo fino a che l'accesso diventi possibile; il primo
 ad introdurre questa nuova interfaccia, chiamata usualmente \textit{I/O
   multiplexing}, è stato BSD, con l'introduzione della funzione \func{select},
@@ -75,7 +74,7 @@ Attende che un certo insieme di file descriptor cambi stato.
   qual caso \var{errno} viene settata ai valori:
   \begin{errlist}
   \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato in uno
   qual caso \var{errno} viene settata ai valori:
   \begin{errlist}
   \item[\macro{EBADF}] Si è specificato un file descriptor sbagliato in uno
-  degeli insiemi.
+  degli insiemi.
   \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
   \item[\macro{EINVAL}] Si è specificato per \param{n} un valore negativo.
   \end{errlist}
   \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
   \item[\macro{EINVAL}] Si è specificato per \param{n} un valore negativo.
   \end{errlist}
@@ -115,8 +114,7 @@ In genere un \textit{file descriptor set} pu
 il limite del numero massimo di file aperti\footnote{ad esempio in Linux, fino
   alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma quando,
 come nelle versioni più recenti del kernel, questo limite non c'è un massimo,
 il limite del numero massimo di file aperti\footnote{ad esempio in Linux, fino
   alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma quando,
 come nelle versioni più recenti del kernel, questo limite non c'è un massimo,
-esso indica le dimensioni in munero di bit utilizzabili per l'insieme.
-
+esso indica le dimensioni in numero di bit utilizzabili per l'insieme.
 
 La funzione richiede di specificare tre insiemi distinti di file descriptor;
 il primo, \param{readfds}, verrà osservato per rilevare la disponibilità di
 
 La funzione richiede di specificare tre insiemi distinti di file descriptor;
 il primo, \param{readfds}, verrà osservato per rilevare la disponibilità di
@@ -186,7 +184,7 @@ riporta il file descriptor che ha generato il segnale.
 \section{Il file locking}
 \label{sec:file_locking}
 
 \section{Il file locking}
 \label{sec:file_locking}
 
-In \secref{sec:file_sharing} abbiamo preso in esame le mosalità in cui un
+In \secref{sec:file_sharing} abbiamo preso in esame le modalità in cui un
 sistema unix-like gestisce la condivisione dei file da parte di processi
 diversi. In quell'occasione si è visto come, con l'eccezione dei file aperti
 in \textit{append mode}, quando più processi scrivono contemporaneamente sullo
 sistema unix-like gestisce la condivisione dei file da parte di processi
 diversi. In quell'occasione si è visto come, con l'eccezione dei file aperti
 in \textit{append mode}, quando più processi scrivono contemporaneamente sullo
@@ -196,7 +194,7 @@ Questo causa la possibilit
 generale le situazioni più comuni sono due: l'interazione fra un processo che
 scrive e altri che leggono, in cui questi ultimi possono leggere informazioni
 scritte solo in maniera parziale o incompleta; o quella in cui diversi
 generale le situazioni più comuni sono due: l'interazione fra un processo che
 scrive e altri che leggono, in cui questi ultimi possono leggere informazioni
 scritte solo in maniera parziale o incompleta; o quella in cui diversi
-processi scrivono, mescolando in maniera imprevedebile il loro output sul
+processi scrivono, mescolando in maniera imprevedibile il loro output sul
 file.
 
 In tutti questi casi il \textit{file locking} è la tecnica che permette di
 file.
 
 In tutti questi casi il \textit{file locking} è la tecnica che permette di
diff --git a/ipc.tex b/ipc.tex
index c16d5c32ea8486a3d50d94697642579f590e5190..d8703b1e1b102f5fafe4f73e4f576ea0105db450 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -125,7 +125,7 @@ da altri processi.
 Per capire meglio il funzionamento di una pipe faremo un esempio di quello che
 è il loro uso più comune, analogo a quello effettuato della shell, e che
 consiste nell'inviare l'output di un processo (lo standard output) sull'input
 Per capire meglio il funzionamento di una pipe faremo un esempio di quello che
 è il loro uso più comune, analogo a quello effettuato della shell, e che
 consiste nell'inviare l'output di un processo (lo standard output) sull'input
-di un'altro. Realizzaremo il programma nella forma di un
+di un'altro. Realizzeremo il programma nella forma di un
 \textit{CGI}\footnote{Un CGI (\textit{Common Gateway Interface}) è un programma
   che permette la creazione dinamica di un oggetto da inserire all'interno di
   una pagina HTML.}  per apache, che genera una immagine JPEG di un codice a
 \textit{CGI}\footnote{Un CGI (\textit{Common Gateway Interface}) è un programma
   che permette la creazione dinamica di un oggetto da inserire all'interno di
   una pagina HTML.}  per apache, che genera una immagine JPEG di un codice a
@@ -168,7 +168,8 @@ file.\footnote{il problema potrebbe essere superato determinando in anticipo
   un nome appropriato per il file temporaneo, che verrebbe utilizzato dai vari
   sotto-processi, e cancellato alla fine della loro esecuzione; ma a questo le
   cose non sarebbero più tanto semplici.}  L'uso di una pipe invece permette
   un nome appropriato per il file temporaneo, che verrebbe utilizzato dai vari
   sotto-processi, e cancellato alla fine della loro esecuzione; ma a questo le
   cose non sarebbero più tanto semplici.}  L'uso di una pipe invece permette
-di risolvere il problema in maniera semplice ed elegante.
+di risolvere il problema in maniera semplice ed elegante, oltre ad essere
+molto più efficiente, dato che non si deve scrivere su disco.
 
 Il programma ci servirà anche come esempio dell'uso delle funzioni di
 duplicazione dei file descriptor che abbiamo trattato in
 
 Il programma ci servirà anche come esempio dell'uso delle funzioni di
 duplicazione dei file descriptor che abbiamo trattato in
@@ -523,8 +524,56 @@ stare molto attenti alla possibili deadlock.\footnote{se si cerca di leggere
   processo si blocca e non potrà quindi mai eseguire le funzioni di
   scrittura.}
 
   processo si blocca e non potrà quindi mai eseguire le funzioni di
   scrittura.}
 
-L'impiego più comune per le fifo è quello che le vede impegnate con un
-processo in 
+Per la loro caratteristica di essere accessibili attraverso il filesystem, è
+piuttosto frequente l'utilizzo di una fifo come canale di comunicazione nelle
+situazioni un processo deve ricevere informazioni dagli altri. In questo caso
+è fondamentale che le operazioni di scrittura siano atomiche; per questo si
+deve sempre tenere presente che questo è vero soltanto fintanto che non si
+supera il limite delle dimensioni di \macro{PIPE\_BUF} (si ricordi quanto
+detto in \secref{sec:ipc_pipes}).
+
+A parte il precedente, che resta probabilmente il più comune, Stevens riporta
+in \cite{APUE} altre due casistiche principali per l'uso delle fifo:
+\begin{itemize}
+\item Da parte dei comandi di shell, per evitare la creazione di file
+  temporanei quando si devono inviare i dati di uscita di un processo
+  sull'input di parecchi altri (attraverso l'uso del comando \cmd{tee}).
+  
+\item Come canale di comunicazione fra un client ed un server (il modello
+  \textit{client-server} è illustrato in \secref{sec:net_cliserv}).
+\end{itemize}
+
+Nel primo caso quello che si fa è creare tante pipe quanti sono i processi a
+cui i vogliono inviare i dati, da usare come standard input per gli stessi; una
+volta che li si saranno posti in esecuzione ridirigendo lo standard input si
+potrà eseguire il processo iniziale replicandone, con il comando \cmd{tee},
+l'output sulle pipe.
+
+Il secondo caso è relativamente semplice qualora si debba comunicare con un
+processo alla volta (nel qual caso basta usare due pipe, una per leggere ed
+una per scrivere), le cose diventano invece molto più complesse quando si
+vuole effettuare una comunicazione fra il server ed un numero imprecisato di
+client; se il primo infatti può ricevere le richieste attraverso una fifo
+``nota'', per le risposte non si può fare altrettanto, dato che per la
+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 diversi meccanismi di
+comunicazione, come quelli che esamineremo in \secref{sec:ipc_sysv}.
+
 
 
 \section{La comunicazione fra processi di System V}
 
 
 \section{La comunicazione fra processi di System V}
@@ -532,11 +581,12 @@ processo in
 
 Benché le pipe (e le fifo) siano ancora ampiamente usate, esse presentano
 numerosi limiti, il principale dei quali è che il meccanismo di comunicazione
 
 Benché le pipe (e le fifo) siano ancora ampiamente usate, esse presentano
 numerosi limiti, il principale dei quali è che il meccanismo di comunicazione
-è rigidamente sequenziale; una situazione in cui un processo scrive qualcosa
-che molti altri devono poter leggere non può essere implementata con una pipe.
+è rigidamente sequenziale; per cui una situazione in cui un processo scrive
+qualcosa che molti altri devono poter leggere non può essere implementata in
+maniera semplice con una pipe.
 
 
-Per superarne i vari limiti, nello sviluppo di System V vennero introdotti una
-serie di nuovi oggetti di comunicazione e relative interfacce id
+Per superarne questi limiti nello sviluppo di System V vennero introdotti una
+serie di nuovi oggetti di comunicazione e relative interfacce di
 programmazione che garantissero una maggiore flessibilità; in questa sezione
 esamineremo quello che viene ormai chiamato il \textsl{Sistema di
   comunicazione inter-processo} di System V , più comunemente noto come
 programmazione che garantissero una maggiore flessibilità; in questa sezione
 esamineremo quello che viene ormai chiamato il \textsl{Sistema di
   comunicazione inter-processo} di System V , più comunemente noto come
index 7c0fbc798f1b492b0e55c014acf15b40305b393f..49e4eb244b47135c859f55f593d631a412b2468a 100644 (file)
@@ -23,9 +23,9 @@ monolitico all'interno del quale vengono eseguite tutte le istruzioni, e
 presuppone un sistema operativo ``multitasking'' in grado di eseguire processi
 diversi.
 
 presuppone un sistema operativo ``multitasking'' in grado di eseguire processi
 diversi.
 
-Il concetto fondamentale si basa la programmazione di rete sotto Linux (e
-sotto Unix in generale) è il modello \textit{client-server} in cui un
-programma di servizio, il \textit{server} riceve un connessione e risponde a
+Un concetto fondamentale su cui si basa la programmazione di rete sotto Linux
+(e sotto Unix in generale) è il modello \textit{client-server} in cui un
+programma di servizio, il \textit{server}, riceve una connessione e risponde a
 un programma di utilizzo, il \textit{client}, provvedendo a quest'ultimo un
 definito insieme di servizi.
 
 un programma di utilizzo, il \textit{client}, provvedendo a quest'ultimo un
 definito insieme di servizi.
 
index e57e8ca84558fd05cf2e11e27dab49b7a9eaad6b..e3e08e44bed80683b2cff98d8f4ee088dcbe3a79 100644 (file)
@@ -386,9 +386,11 @@ sul numero totale di processi permessi all'utente (vedi
 L'uso di \func{fork} avviene secondo due modalità principali; la prima è
 quella in cui all'interno di un programma si creano processi figli cui viene
 affidata l'esecuzione di una certa sezione di codice, mentre il processo padre
 L'uso di \func{fork} avviene secondo due modalità principali; la prima è
 quella in cui all'interno di un programma si creano processi figli cui viene
 affidata l'esecuzione di una certa sezione di codice, mentre il processo padre
-ne esegue un'altra. È il caso tipico dei server di rete in cui il padre riceve
-ed accetta le richieste da parte dei client, per ciascuna delle quali pone in
-esecuzione un figlio che è incaricato di fornire il servizio.
+ne esegue un'altra. È il caso tipico dei server (il modello
+\textit{client-server} è illustrato in \secref{sec:net_cliserv}) di rete in
+cui il padre riceve ed accetta le richieste da parte dei client, per ciascuna
+delle quali pone in esecuzione un figlio che è incaricato di fornire il
+servizio.
 
 La seconda modalità è quella in cui il processo vuole eseguire un altro
 programma; questo è ad esempio il caso della shell. In questo caso il processo
 
 La seconda modalità è quella in cui il processo vuole eseguire un altro
 programma; questo è ad esempio il caso della shell. In questo caso il processo