2021-01-20 14:53:48 +11:00
|
|
|
\chapter{IPC} \index{IPC}
|
|
|
|
\label{chap:IPC}
|
|
|
|
|
|
|
|
\textit{Inter Process Communication.}
|
|
|
|
|
2021-05-04 19:33:30 +11:00
|
|
|
Il existe deux familles bien distinctes. Nous allons donc
|
2021-08-25 16:18:34 +11:00
|
|
|
les voir dans le plus grand des désordres, en commençant
|
|
|
|
par les grands classiques.
|
2021-05-04 19:33:30 +11:00
|
|
|
|
2021-01-20 14:53:48 +11:00
|
|
|
% ================================================================
|
|
|
|
|
2022-01-20 09:31:51 +11:00
|
|
|
% https://lwn.net/Articles/414618/
|
|
|
|
% https://lwn.net/ml/linux-kernel/20220103181956.983342-1-walt@drummond.us/
|
|
|
|
|
2021-08-18 18:49:28 +11:00
|
|
|
\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}
|
|
|
|
|
2021-08-19 03:52:09 +11:00
|
|
|
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.
|
|
|
|
|
2021-08-18 18:49:28 +11:00
|
|
|
\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}
|
2021-01-20 14:53:48 +11:00
|
|
|
|
2021-08-19 03:52:09 +11:00
|
|
|
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
|
|
|
|
|
2021-01-20 14:53:48 +11:00
|
|
|
% ================================================================
|
|
|
|
|
2024-09-18 03:57:20 +11:00
|
|
|
\section{Les sockets Unix} \index{socket}
|
|
|
|
|
|
|
|
Les sockets de la famille AF\_UNIX sont utilisés pour
|
|
|
|
les communications locales entre applications sur une même machine.
|
2021-01-20 14:53:48 +11:00
|
|
|
|
|
|
|
% ================================================================
|
|
|
|
|
2021-08-18 18:49:28 +11:00
|
|
|
\section{shared memory} \index{shared}
|
2021-01-20 14:53:48 +11:00
|
|
|
|
2021-08-18 18:49:28 +11:00
|
|
|
Mémoire partagée.
|
2021-01-20 14:53:48 +11:00
|
|
|
|
|
|
|
% ================================================================
|
|
|
|
|
2021-08-25 16:18:34 +11:00
|
|
|
\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.
|
|
|
|
|
2021-08-29 02:06:26 +11:00
|
|
|
% ----------------------------------------------------------------
|
|
|
|
|
2021-08-25 16:18:34 +11:00
|
|
|
\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}
|
|
|
|
|
2021-08-29 02:06:26 +11:00
|
|
|
Vous remarquerez que nous nettoyons le message avant utilisation
|
|
|
|
avec un \texttt{memset(3)}, une étape trop souvent oubliée.
|
|
|
|
|
|
|
|
% ----------------------------------------------------------------
|
|
|
|
|
2021-08-25 16:18:34 +11:00
|
|
|
\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
|
2021-08-29 02:06:26 +11:00
|
|
|
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
|
|
|
|
|
|
|
|
% ----------------------------------------------------------------
|
2021-08-25 16:18:34 +11:00
|
|
|
|
|
|
|
\subsection{Timestamp} \index{timestamp}
|
|
|
|
|
|
|
|
Comme promis un peu plus haut, le code est très simple.
|
2023-10-14 07:05:00 +11:00
|
|
|
C'est juste dommage qu'une fonction aussi utile ne fasse
|
|
|
|
pas partie de la \textsl{stdlib} du langage C\index{C},
|
|
|
|
alors qu'elle le mérite.
|
2021-08-25 16:18:34 +11:00
|
|
|
|
|
|
|
\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}
|
|
|
|
|
2021-08-29 02:06:26 +11:00
|
|
|
% ----------------------------------------------------------------
|
|
|
|
|
2021-08-25 16:18:34 +11:00
|
|
|
\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.
|
|
|
|
|
2021-08-29 02:06:26 +11:00
|
|
|
% ----------------------------------------------------------------
|
|
|
|
|
2021-08-25 16:18:34 +11:00
|
|
|
% ================================================================
|
|
|
|
|
2021-08-18 18:49:28 +11:00
|
|
|
|
2021-01-20 14:53:48 +11:00
|
|
|
|