From: Simone Piccardi Date: Fri, 28 Jun 2002 21:07:21 +0000 (+0000) Subject: Nuovo esempio (funzionante) e primo abbozzo delle spiegazioni delle fifo. X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=31ab2d2cca0ca061a00cd688c850fca860827e26;p=gapil.git Nuovo esempio (funzionante) e primo abbozzo delle spiegazioni delle fifo. --- diff --git a/ipc.tex b/ipc.tex index 898305f..e563153 100644 --- 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 diff --git a/sources/BarCode.c b/sources/BarCode.c index fbea4ae..4164acf 100644 --- a/sources/BarCode.c +++ b/sources/BarCode.c @@ -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])); }