TetaTricks/chap/IPC.tex

169 lines
5.4 KiB
TeX

\chapter{IPC} \index{IPC}
\label{chap:IPC}
\textit{Inter Process Communication.}
Il existe deux familles bien distinctes. Nous allons donc
les voir dans le plus grand des désordres, en commençant
par les grands classiques.
% ================================================================
\section{Signal} \index{signal}
nous allonc commencer par le plus simple mécanisme d'IPC~:
le signal.
Et pour ça, nous allons utiliser (encore une fois ?) un exemple
futile, certes, mais simple à comprendre.
Nous avons un programme qui tourne en boucle en effectuant des
taches complexes (simulées pour l'exemple par une nanosieste) et
nous souhaitons pouvoir lui demander d'afficher l'avancée de la
chose.
\label{get-signal}
\lstinputlisting[language=c]{code/get-signal.c}
Quand ce processus recevra le signal, la fonction \texttt{attraper}
sera appelée de façon \textsl{asynchrone} et positionnera le drapeau.
C'est dans le terme \textsl{asynchrone} que le diable a caché
les détails.
\begin{verbatim}
fubar $ ./get-signal &
[1] 14001
fubar $ kill me, my pid is 14001
kill -USR1 14001
fubar $ count is 22
kill %1
fubar $
[1]+ Terminated ./get-signal
fubar $
\end{verbatim}
Comme on peut le constater, le principe est simple. Un signal est
une interruption d'un processus qui, en dehors de sa présence, ne
transfère que peu d'information. Le principe est simple, d'accord,
mais la mise en œuvre l'est moins.
Cet exemple peut être considéré comme obsolète, et la
\textsl{manpage}\footnote{Mais qui lit le man, de nos jours ?}
confime bien.
\begin{quote}
The only portable use of signal() is to set a signal's disposition to
SIG\_DFL or SIG\_IGN. The semantics when using signal() to establish a
signal handler vary across systems (and POSIX.1 explicitly permits this
variation); \textbf{do not use it for this purpose}.
\end{quote}
Vous voilà prévenus, la suite bientôt\dots
% ================================================================
% ================================================================
\section{shared memory} \index{shared}
Mémoire partagée.
% ================================================================
\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}
Vous remarquerez que nous nettoyons le message avant utilisation
avec un \texttt{memset(3)}, une étape trop souvent oubliée.
% ----------------------------------------------------------------
\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, mais la lecture de
\texttt{fifo(7)} et de \texttt{pipe(7)} peut être
utile pour comprendre\footnote{modulo les références circulaires.}
la chose\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.
% ----------------------------------------------------------------
% ================================================================