Como uma fila de mensagens é implementada no kernel do Linux?

28

Eu gostaria de saber como as Filas de Mensagens são implementadas no Kernel do Linux.

    
por Sen 05.02.2011 / 11:05

1 resposta

39

O kernel Linux (2.6) implementa duas filas de mensagens:
(em vez disso, 'listas de mensagens', como a implementação é feita usando uma lista vinculada não seguindo estritamente o princípio FIFO)

Mensagens IPC do sistema V

A fila de mensagens do System V.

Um processo pode invocar msgsnd() para enviar uma mensagem. Ele precisa passar o identificador de IPC da fila de mensagens de recebimento, o tamanho da mensagem e uma estrutura de mensagem, incluindo o tipo de mensagem e o texto.

Por outro lado, um processo invoca msgrcv() para receber uma mensagem, passando o identificador IPC da fila de mensagens, onde a mensagem deve ser armazenada, o tamanho e um valor t .

t especifica a mensagem retornada da fila, um valor positivo significa que a primeira mensagem com seu tipo igual a t é retornada, um valor negativo retorna a última mensagem igual para digitar t e zero retorna a primeira mensagem da fila.

Essas funções são definidas em include / linux / msg.h e implementado em ipc / msg.c

Existem limitações quanto ao tamanho de uma mensagem (max), ao número total de mensagens (mni) e ao tamanho total de todas as mensagens na fila (mnb):

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

A saída acima é de um sistema Ubuntu 10.10, os padrões são definidos em msg .h .

Mais uma fila de mensagens do System V incrivelmente antiga explicada aqui .

Fila de mensagens POSIX

O padrão POSIX define um mecanismo de fila de mensagens baseado na fila de mensagens do System V IPC, estendendo-o por algumas funcionalidades:

  • Interface simples baseada em arquivo para o aplicativo
  • Suporte para prioridades de mensagens
  • Suporte para notificação assíncrona
  • Tempos limite para operações de bloqueio

Veja ipc / mqueue.c

Exemplo

util-linux fornece alguns programas para analisar e modificar filas de mensagens e a especificação POSIX fornece alguns exemplos C:

Crie uma fila de mensagens com ipcmk ; geralmente você faria isso chamando funções C como ftok() e msgget() :

$ ipcmk -Q

Vamos ver o que aconteceu usando ipcs ou com cat /proc/sysvipc/msg :

$ ipcs -q

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

Agora preencha a fila com algumas mensagens:

$ 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

Novamente, você geralmente não codifica o msqid no 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        

E o outro lado, que receberá as mensagens:

$ 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

Veja o que acontece:

$ 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           

Após dois recebimentos, a fila fica vazia novamente.

Remova-o depois, especificando a chave ( -Q ) ou msqid ( -q ):

$ ipcrm -q 65536
    
por 05.02.2011 / 14:26

Tags