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:
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},
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}
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
\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
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
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
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
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}
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