¿Cómo se implementa una cola de mensajes en el kernel de Linux?

29

Me gustaría saber cómo se implementan las colas de mensajes en el kernel de Linux.

Sen
fuente
IPC_NOWAIT lo usamos solo en el receptor
Anwaar Qa

Respuestas:

41

El kernel de Linux (2.6) implementa dos colas de mensajes:
(en lugar de 'listas de mensajes', ya que la implementación se realiza utilizando una lista vinculada que no sigue estrictamente el principio FIFO)

Mensajes de System V IPC

La cola de mensajes del Sistema V.

Un proceso puede invocar msgsnd()para enviar un mensaje. Necesita pasar el identificador de IPC de la cola de mensajes de recepción, el tamaño del mensaje y una estructura de mensaje, incluido el tipo de mensaje y el texto.

Por otro lado, un proceso invoca msgrcv()para recibir un mensaje, pasando el identificador IPC de la cola de mensajes, dónde debe almacenarse el mensaje, el tamaño y un valor t .

t especifica el mensaje devuelto por la cola, un valor positivo significa que se devuelve el primer mensaje con su tipo igual a t , un valor negativo devuelve el último mensaje igual al tipo t y cero devuelve el primer mensaje de la cola.

Estas funciones se definen en include / linux / msg.h y se implementan en ipc / msg.c

Existen limitaciones sobre el tamaño de un mensaje (máx.), El número total de mensajes (mni) y el tamaño total de todos los mensajes en la cola (mnb):

$ sysctl kernel.msg{max,mni,mnb}
kernel.msgmax = 8192
kernel.msgmni = 1655
kernel.msgmnb = 16384

La salida anterior es de un sistema Ubuntu 10.10, los valores predeterminados se definen en msg.h .

Aquí se explican más cosas de la cola de mensajes del Sistema V increíblemente antiguas .

Cola de mensajes POSIX

El estándar POSIX define un mecanismo de cola de mensajes basado en la cola de mensajes de System V IPC, extendiéndolo por algunas funcionalidades:

  • Interfaz simple basada en archivos para la aplicación.
  • Apoyo a las prioridades de los mensajes.
  • Soporte para notificaciones asincrónicas
  • Tiempos de espera para bloquear operaciones

Ver ipc / mqueue.c

Ejemplo

util-linux proporciona algunos programas para analizar y modificar las colas de mensajes y la especificación POSIX ofrece algunos ejemplos de C:

Crea una cola de mensajes con ipcmk; generalmente haría esto llamando a funciones C como ftok()y msgget():

$ ipcmk -Q

Veamos qué pasó usando ipcso con un cat /proc/sysvipc/msg:

$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x33ec1686 65536      user       644        0            0           

Ahora llena la cola con algunos mensajes:

$ 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

Una vez más, generalmente no codifica el msqid en el código.

$ 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        

Y el otro lado, que recibirá los mensajes:

$ 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

Mira qué pasa:

$ 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           

Después de dos recibos, la cola vuelve a estar vacía.

Elimínelo luego especificando la clave ( -Q) o msqid ( -q):

$ ipcrm -q 65536
meneo
fuente
Entonces, ¿el mensaje (tipo y texto) se clona / copia y luego esa copia se coloca en la cola de mensajes del sistema?
trusktr
Muy bien puesto. Gracias por esta asombrosa explicación.
Usuario9102d82