web-dev-qa-db-fra.com

Comment une file d'attente de message est-elle implémentée dans le noyau Linux?

J'aimerais savoir comment les files d'attente de messagerie sont implémentées dans le noyau Linux.

29
Sen

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:

  • Interface de fichier simple à l'application
  • Soutien aux priorités de message
  • Soutien à la notification asynchrone
  • Timeouts pour les opérations de blocage

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
40
wag