J'aimerais savoir comment les files d'attente de messagerie sont implémentées dans le noyau Linux.
Le noyau Linux (2.6) implémente deux files d'attente de message:
(plutôt "Listes de messages", car la mise en œuvre est effectuée à l'aide d'une liste liée non strictement suivant le principe FIFO)
Système V IPC Messages
La file d'attente de message du système V.
Un processus peut invoquer msgsnd()
pour envoyer un message. Il a besoin de passer l'identifiant IPC de la file d'attente de message récepteur, la taille du message et une structure de message, y compris le type de message et le texte.
De l'autre côté, un processus invoque msgrcv()
pour recevoir un message, en passant l'identifiant IPC de la file d'attente de messages, où le message doit être stocké, la taille et une valeur t.
T Spécifie le message renvoyé à partir de la file d'attente, une valeur positive signifie le premier message avec son type égal à t est renvoyé, une valeur négative renvoie le dernier message. égal à type t et zéro renvoie le premier message de la file d'attente.
Ces fonctions sont définies dans Inclure/Linux/msg.h et implémentées dans IPC/msg.c
Il existe des limites sur la taille d'un message (max), le nombre total de messages (MNI) et la taille totale de tous les messages de la file d'attente (MNB):
$ sysctl kernel.msg{max,mni,mnb}
kernel.msgmax = 8192
kernel.msgmni = 1655
kernel.msgmnb = 16384
La sortie ci-dessus provient d'un système Ubuntu 10.10, les valeurs par défaut sont définies dans msg.h .
Plus incroyablement ancien System V Message File d'attente expliquée ici .
File d'attente de message POSIX
La norme POSIX définit un mécanisme de file d'attente de message basé sur la file d'attente du système V IPC, en prolongeant certaines fonctionnalités:
Voir IPC/MQUE.C
exemple
util-linux
Fournit certains programmes d'analyse et de modification des files d'attente de messages et la spécification POSIX donne certains exemples C:
Créez une file d'attente de message avec ipcmk
; Généralement, vous le feriez en appelant C Fonctions C comme ftok()
et msgget()
:
$ ipcmk -Q
Permet de voir ce qui s'est passé en utilisant ipcs
ou avec un cat /proc/sysvipc/msg
:
$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x33ec1686 65536 user 644 0 0
Remplissez maintenant la file d'attente avec des messages:
$ cat <<EOF >msg_send.c
#include <string.h>
#include <sys/msg.h>
int main() {
int msqid = 65536;
struct message {
long type;
char text[20];
} msg;
msg.type = 1;
strcpy(msg.text, "This is message 1");
msgsnd(msqid, (void *) &msg, sizeof(msg.text), IPC_NOWAIT);
strcpy(msg.text, "This is message 2");
msgsnd(msqid, (void *) &msg, sizeof(msg.text), IPC_NOWAIT);
return 0;
}
EOF
Encore une fois, vous ne connaissez généralement pas le système MSQID dans le code.
$ gcc -o msg_send msg_send.c
$ ./msg_send
$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x33ec1686 65536 user 644 40 2
Et l'autre côté, qui recevra les messages:
$ cat <<EOF >msg_recv.c
#include <stdio.h>
#include <sys/msg.h>
int main() {
int msqid = 65536;
struct message {
long type;
char text[20];
} msg;
long msgtyp = 0;
msgrcv(msqid, (void *) &msg, sizeof(msg.text), msgtyp, MSG_NOERROR | IPC_NOWAIT);
printf("%s \n", msg.text);
return 0;
}
EOF
Voyez ce qui se passe:
$ gcc -o msg_recv msg_recv.c
$ ./msg_recv
This is message 1
$ ./msg_recv
This is message 2
$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x33ec1686 65536 user 644 0 0
Après deux reçus, la file d'attente est à nouveau vide.
Supprimez-le ensuite en spécifiant la clé (-Q
) Ou msqid (-q
):
$ ipcrm -q 65536