diff --git a/.gitignore b/.gitignore index ec4664a..a256344 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ main.pdf main.toc code/a.out +code/*.o code/foo code/thread-demo code/ex_curses @@ -21,6 +22,5 @@ code/hello code/arguments code/no-op code/get-signal - - - +code/fifo-tx +code/fifo-rx diff --git a/chap/IPC.tex b/chap/IPC.tex index 13e1d7e..0ee3a13 100644 --- a/chap/IPC.tex +++ b/chap/IPC.tex @@ -4,7 +4,8 @@ \textit{Inter Process Communication.} Il existe deux familles bien distinctes. Nous allons donc -les voir dans le plus grand des désordres. +les voir dans le plus grand des désordres, en commençant +par les grands classiques. % ================================================================ @@ -68,7 +69,84 @@ Mémoire partagée. % ================================================================ -\section{named pipe} +\section{named pipe} \label{named-pipe} +\index{fifo} + +Un « FIFO » (ou « tube nommé ») peut être vu comme une sorte de +boite à lettres +dans laquelle on peut glisser un message à l'intention du +processus qui aura crée cette boite, avec un nom pré-défini afin +que l'expéditeur du message sache où le déposer. + +\begin{quote} +A FIFO special file is similar to a pipe, except that it is created in a different way. +Instead of being an anonymous communications channel, a FIFO special file is entered +into the filesystem by calling mkfifo(). +\end{quote} + +Hop, une rapide démonstration. J'avais tout d'abors pensé à un +exemple minimaliste, puis je me suis dit~: « Et pourquoi ne pas +enmbarquer une charge utile dans le message ? », aussitôt dit +aussitôt fait. + +L'émetteur mettra un \textsl{timestamp} dans le corps du message, +et le récepteur affichera l'écart avec le \textsl{timestamp} local. +Ce marqueur temporel sera obtenu par l'appel à +\texttt{gettimeofday(2)} \index{gettimeofday} +pour tenter d'avoir une précision +significative. + +\subsection{Émetteur} + +Son role est simple~: il met le timestamp dans l'enveloppe, et +la poste vers l'adresse qu'on lui passe sur la ligne de commande. + +\lstinputlisting[language=c]{code/fifo-tx.c} + +\subsection{Récepteur} + +Pour faire simple, le récepteur des messages va passer l'intégralité +de son temps scotché devant la boite aux lettres, et attraper le +message dès son arrivée. Dans notre jargon, nous appellons ça +la méthode \textsl{buzzy-wait}. + +Sauf que ça n'est pas tout à fait ça. + +\lstinputlisting[language=c]{code/fifo-rx.c} + +J'avoue ne pas avoir encore bien capté le deuxième argument +de mkfifo\dots + +\subsection{Timestamp} \index{timestamp} + +Comme promis un peu plus haut, le code est très simple. + +\lstinputlisting[language=c]{code/dtime.c} + +Cecit dit, la précision, ou plutôt la résolution, +est très dépendante du matériel, +de sa gestion par le système d'exploitation, +et et aussi\footnote{Mais faut-il s'étonner ?} +du \textsc{bofh} local. + +\begin{quote} +The time returned by gettimeofday() is affected by discontinuous jumps +in the system time (e.g., if the system administrator manually changes +the system time). If you need a monotonically increasing clock, see +clock\_gettime(2). +\end{quote} + +\subsection{Message} + +Pour des raisons pas si évidente que ça, les messages transmis +doivent tous avoir la même taille. Nous allons donc définir +une structure (page ???) contenant les données à transmettre. + +\lstinputlisting[language=c]{code/my-fifo.h} + +C'est rudimentaire, mais ça fera l'affaire pour claquer un Bonaldi. + +% ================================================================ + -Tube nommé. diff --git a/code/Makefile b/code/Makefile index c55f8dc..f118b4a 100644 --- a/code/Makefile +++ b/code/Makefile @@ -19,5 +19,17 @@ arguments: arguments.c Makefile no-op: no-op.c Makefile gcc -Wall $< -o $@ +#------------- IPC + get-signal: get-signal.c Makefile gcc -Wall $< -o $@ + +dtime.o: dtime.c my-fifo.h Makefile + gcc -Wall -c $< + +fifo-tx: fifo-tx.c my-fifo.h dtime.o Makefile + gcc -Wall $< dtime.o -o $@ + +fifo-rx: fifo-rx.c my-fifo.h dtime.o Makefile + gcc -Wall $< dtime.o -o $@ + diff --git a/code/dtime.c b/code/dtime.c new file mode 100644 index 0000000..8d116f8 --- /dev/null +++ b/code/dtime.c @@ -0,0 +1,9 @@ +#include +#include + +double dtime(void) +{ +struct timeval tv; +gettimeofday(&tv, NULL); +return (double)tv.tv_sec + ((double)tv.tv_usec)/1e6; +} \ No newline at end of file diff --git a/code/fifo-rx.c b/code/fifo-rx.c new file mode 100644 index 0000000..29a9440 --- /dev/null +++ b/code/fifo-rx.c @@ -0,0 +1,27 @@ +/*** named pipe --- receiver ***/ + +#include +#include +#include +#include /* for mkfifo */ +#include +#include "my-fifo.h" + +int main(int argc, char *argv[]) +{ +int fifo; +Message message; +double localTS; + +if (argc!=2) exit(1); +fifo = mkfifo(argv[1], 0400); +if (fifo) { + perror("mkfifo fail"); + exit(2); + } +read(fifo, &message, sizeof(Message)); +localTS = dtime(); +printf("%f %f\n", localTS, message.timestamp); +close(fifo); +return 0; +} \ No newline at end of file diff --git a/code/fifo-tx.c b/code/fifo-tx.c new file mode 100644 index 0000000..72967c7 --- /dev/null +++ b/code/fifo-tx.c @@ -0,0 +1,24 @@ +/*** named pipe --- transmiter ***/ +#include +#include +#include +#include +#include "my-fifo.h" + +int main(int argc, char *argv[]) +{ +int fifo; +Message message; + +if (argc!=2) exit(1); +if (-1==(fifo = open(argv[1], O_WRONLY))) { + perror("open fifo for wr"); + exit(1); + } +message.pid = getpid(); +message.timestamp = dtime(); +write(fifo, &message, sizeof(Message)); +close(fifo); + +return 0; +} \ No newline at end of file diff --git a/code/my-fifo.h b/code/my-fifo.h new file mode 100644 index 0000000..ca990f8 --- /dev/null +++ b/code/my-fifo.h @@ -0,0 +1,7 @@ +typedef struct { + int pid; + double timestamp; + long notused; + } Message; + +double dtime(void); \ No newline at end of file