Nuovo esempio (funzionante) e primo abbozzo delle spiegazioni delle fifo.
authorSimone Piccardi <piccardi@gnulinux.it>
Fri, 28 Jun 2002 21:07:21 +0000 (21:07 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Fri, 28 Jun 2002 21:07:21 +0000 (21:07 +0000)
ipc.tex
sources/BarCode.c

diff --git a/ipc.tex b/ipc.tex
index 898305fdd703de19aeb56ca31e5e53d9f23f2bb6..e5631536c274f154f1304afa51cb82241931b9e3 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -102,7 +102,6 @@ devono comunque derivare da uno stesso processo padre che ha aperto la pipe,
 o, più comunemente, essere nella relazione padre/figlio.
 
 
-
 \subsection{Un esempio dell'uso delle pipe}
 \label{sec:ipc_pipe_use}
 
@@ -110,9 +109,10 @@ 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
-\textit{cgi}\footnote{NdA, inserire una breve descrizione di cosa è un cgi.}
-per apache, che genera una immagine JPEG di un codice a barre, specificato
-come parametro di input.
+\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
+barre, specificato come parametro di input.
 
 Un programma che deve essere eseguito come \textit{cgi} per apache deve
 rispondere a delle caratteristiche specifiche, esso infatti non viene lanciato
@@ -125,7 +125,6 @@ ed il risultato dell'elaborazione deve essere presentato (con una intestazione
 che ne descrive il mime-type) sullo standard output, in modo che apache possa
 reinviarlo al browser che ha effettuato la richiesta.
 
-
 Per fare questo useremo in sequenza i programmi \cmd{barcode} e \cmd{gs}, il
 primo infatti è in grado di generare immagini postscript di codici a barre
 corrispondenti ad una qualunque stringa, mentre il secondo serve per poter
@@ -241,29 +240,29 @@ scriver
 
 Dall'altra parte il processo padre prima chiude (\texttt{\small 26}) il capo
 inutilizzato della prima pipe (quello in input), poi scrive (\texttt{\small
-  27}) la stringa da convertire sul capo in output così che \cmd{barcode}
+  27}) la stringa da convertire sul capo in output, così che \cmd{barcode}
 possa riceverla dallo standard input; a questo punto l'uso della prima pipe è
 finito ed essa può essere definitivamente chiusa (\texttt{\small 28}), si
 attende poi (\texttt{\small 29}) che l'esecuzione di \cmd{barcode} sia
 completata.
 
-Alla conclusione della sua esecuzione \cmd{barcode} avrà effettuato inviato
-l'immagine postscript del codice a barre sul capo in scrittura della seconda
-pipe; a questo punto si può eseguire la seconda conversione, da PS a JPEG,
-usando il programma \cmd{gs}. Per questo si crea (\texttt{\small 30--34}) un
-secondo processo figlio, che poi (\texttt{\small 35--42}) eseguirà questo
-programma leggendo l'immagine postscript creata da \cmd{barcode} sullo
-standard input per convertirla in JPEG.
+Alla conclusione della sua esecuzione \cmd{barcode} avrà inviato l'immagine
+postscript del codice a barre sul capo in scrittura della seconda pipe; a
+questo punto si può eseguire la seconda conversione, da PS a JPEG, usando il
+programma \cmd{gs}. Per questo si crea (\texttt{\small 30--34}) un secondo
+processo figlio, che poi (\texttt{\small 35--42}) eseguirà questo programma
+leggendo l'immagine postscript creata da \cmd{barcode} dallo standard input,
+per convertirla in JPEG.
 
 Per fare tutto ciò il secondo figlio anzitutto chiude (\texttt{\small 37}) il
-capo in scrittura della seconda pipe, e collega (\texttt{\small 38}) il capo
-in lettura allo standard input. Per poter formattare l'output del programma in
-maniera utilizzabile da un browser, si provvede anche \texttt{\small 40}) alla
-scrittura dell'apposita stringa di mime-type in testa allo standard output. A
-questo punto si può invocare \texttt{\small 41}) il programma \cmd{gs},
-provvedendo gli appositi switch che consentono di leggere il file da
-convertire dallo standard input, ed inviare la conversione sullo standard
-output.
+capo in scrittura della seconda pipe, e ne collega (\texttt{\small 38}) il
+capo in lettura allo standard input. Per poter formattare l'output del
+programma in maniera utilizzabile da un browser, si provvede anche
+\texttt{\small 40}) alla scrittura dell'apposita stringa di mime-type in testa
+allo standard output. A questo punto si può invocare \texttt{\small 41}) il
+programma \cmd{gs}, provvedendo gli appositi switch che consentono di leggere
+il file da convertire dallo standard input, ed inviare la conversione sullo
+standard output.
 
 Per concludere le operazioni il processo padre chiude \texttt{\small 44}) il
 capo in scrittura della seconda pipe, e attende la conclusione del figlio
@@ -337,8 +336,54 @@ ulteriore programma, \cmd{epstopsf}, per convertire in PDF il file EPS
 generato da \cmd{barcode}. Utilizzando un file in PDF invece, \cmd{gs} esegue
 la conversione rispettando le dimensioni originarie del codice a barre.
 
+Ci si trova dunque davanti al classico caso dell'uso delle pipe in cui si
+devono eseguire più processi in fila, inviando l'output di ciascuno all'input
+del successivo, per poi ottenere il risultato finale sullo standard output.
+Dato che questo caso ciascun processo deve scrivere il suo output sullo
+standard input del successivo, occorrerà usare \func{popen} aprendo la pipe in
+scrittura.
+
+Il codice del nuovo programma è riportato in \figref{fig:ipc_barcode2_code};
+come si può notare l'ordine di invocazione dei programmi è l'inverso di quello
+in cui ci si aspetta vengano effettivamente eseguiti. Questo non comporta
+nessun problema; infatti la lettura su una pipe è bloccante, per cui ciascun
+processo, per quanto lanciato per primo, si bloccherà in attesa di ricevere
+sullo standard input il risultato dell'elaborazione del precendente, benchè
+quest'ultimo venga invocato dopo.
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}{}
+int main(int argc, char *argv[], char *envp[])
+{
+}
 
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{Codice del \textit{cgi-bin} \cmd{BarCode2}.}
+  \label{fig:ipc_barcode2_code}
+\end{figure}
+
+Nel nostro caso il primo passo (\texttt{\small 12}) è scrivere il mime-type
+sullo standard output; a questo punto il processo padre non necessita più di
+eseguire ulteriori operazioni sullo standard output e può tranquillamente
+provvedere alla redirezione. Il primo processo figlio ad essere invocato
+(\texttt{\small 14}) è necessariamente l'ultimo della sequenza, in quanto è
+lui che deve uscire sullo standard output, gli altri saranno tutti rediretti.
+
+Una volta lanciato il processo finale si può iniziare la catena delle
+redirezioni; ogni volta (\texttt{\small 16} e \texttt{\small 20}) duplicheremo
+il file restituito dalla chiamata precedente a \func{popen} sullo standard
+output, in questo modo alla successiva chiamata di \func{popen} il processo
+eseguito scriverà il suo standard output sulla pipe collegata allo standard
+input del precedente.
+
+Alla fine tutto quello che resta da fare è scrivere (\texttt{\small 22}) la
+stringa del codice a barre sulla pipe collegata allo standard input
+dell'ultimo processo lanciato, e poi chiudere tutte le pipe create con
+\func{pclose}.
 
 
 \subsection{Le \textit{pipe} con nome, o \textit{fifo}}
@@ -352,8 +397,18 @@ caratteristiche delle pipe, ma invece che essere struttura interne del kernel
 visibili solo attraverso un file descriptor comune, possono essere viste
 attraverso un inode che risiede sul filesystem.
 
+Utilizzando una fifo tutti i dati passeranno attraverso un apposito buffer nel
+kernel, senza transitare dal filesystem, l'inode serve solo a fornire un punto
+d'appoggio per i vari processi che permetta loro di accedere alla stessa
+fifo.  
+
+
+
 
-Abbiamo già accennato in \secref{sec:file_mknod}
+Abbiamo già visto in \secref{sec:file_mknod} le modalità che permettono di
+creare una fifo, attraverso le funzioni \func{mknod} e \func{mkfifo}; per
+utilizzarle un processo non avrà che da aprire il relativo file in lettura o
+scrittura (a seconda della direzione che si vuole dare ai dati).
 
 che invece possono risiedere
 sul filesystem, e che i processi possono usare per le comunicazioni senza
index fbea4aee3eb8a5fa8f1cbe83750c6d5ec42ed423..4164acf1b2392782a0d74808fefb5ea1d310057f 100644 (file)
@@ -29,7 +29,7 @@
  * http://localhost/cgi-bin/barcode?string
  * where string is the code to be converted
  *
- * $Id: BarCode.c,v 1.4 2002/06/28 17:59:24 piccardi Exp $ 
+ * $Id: BarCode.c,v 1.5 2002/06/28 21:07:21 piccardi Exp $ 
  *
  ****************************************************************/
 /* 
@@ -69,7 +69,6 @@ int main(int argc, char *argv[], char *envp[])
     int i;
     /* write mime-type to stout */ 
     write(STDOUT_FILENO, content, strlen(content));
-    
     /* execute chain of command */
     for (i=0; i<4; i++) {
        pipe[i] = popen(cmd_string[i], "w");
@@ -77,9 +76,9 @@ int main(int argc, char *argv[], char *envp[])
     }
     /* create barcode (in PS) */
     pipein = popen("barcode", "w");
-    /* send barcode string */
+    /* send barcode string to barcode program */
     write(fileno(pipein), argv[1], strlen(argv[1]));
-    /* close all pipes */
+    /* close all pipes (in reverse order) */
     for (i=4; i==0; i--) {
        pclose((pipe[i]));
     }