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

30

Je voudrais savoir comment les files d'attente de messages sont implémentées dans le noyau Linux.

Sen
la source
IPC_NOWAIT nous l'utilisons uniquement dans le récepteur
Anwaar Qa

Réponses:

41

Le noyau Linux (2.6) implémente deux files d'attente de messages:
(plutôt des 'listes de messages', car l'implémentation se fait en utilisant une liste chaînée ne suivant pas strictement le principe FIFO)

Messages IPC System V

La file d'attente de messages du système V.

Un processus peut invoquer msgsnd()pour envoyer un message. Il doit transmettre l'identifiant IPC de la file d'attente de réception des messages, la taille du message et une structure de message, y compris le type et le texte du message.

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é de la file d'attente, une valeur positive signifie que le premier message de type égal à t est renvoyé, une valeur négative renvoie le dernier message égal au type t et zéro renvoie le premier message de la file d'attente.

Ces fonctions sont définies dans include / linux / msg.h et implémentées dans ipc / msg.c

La taille d'un message (max), le nombre total de messages (mni) et la taille totale de tous les messages dans la file d'attente (mnb) sont limités:

$ 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éfinis dans msg.h .

Plus de choses incroyablement anciennes sur la file d'attente de messages System V expliquées ici .

File d'attente de messages POSIX

La norme POSIX définit un mécanisme de file d'attente de messages basé sur la file d'attente de messages de System V IPC, en l'étendant par certaines fonctionnalités:

  • Interface simple basée sur des fichiers pour l'application
  • Prise en charge des priorités de message
  • Prise en charge de la notification asynchrone
  • Délais d'attente pour les opérations de blocage

Voir ipc / mqueue.c

Exemple

util-linux fournit des programmes pour analyser et modifier les files d'attente de messages et la spécification POSIX donne quelques exemples C:

Créez une file d'attente de messages avec ipcmk; généralement vous le feriez en appelant des fonctions C comme ftok()et msgget():

$ ipcmk -Q

Permet de voir ce qui s'est passé en utilisant ipcsou 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 quelques 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 codez généralement pas le 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 réceptions, la file d'attente est à nouveau vide.

Supprimez-le ensuite en spécifiant la clé ( -Q) ou msqid ( -q):

$ ipcrm -q 65536
remuer
la source
Le message (type et texte) est-il donc cloné / copié, puis cette copie est-elle placée dans la file d'attente de messages du système?
trusktr
très bien mis. Merci pour cette incroyable explication.
User9102d82