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

29

Gostaria de saber como as filas de mensagens são implementadas no kernel do Linux.

Sen
fonte
IPC_NOWAIT podemos usá-lo apenas no receptor
Anwaar Qa

Respostas:

41

O kernel do Linux (2.6) implementa duas filas de mensagens:
(em vez de 'listas de mensagens', pois a implementação é feita usando uma lista vinculada que não segue rigorosamente o princípio FIFO)

Mensagens do sistema V IPC

A fila de mensagens do sistema V.

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

Por outro lado, um processo chama msgrcv()para receber uma mensagem, passando o identificador IPC da fila de mensagens, onde a mensagem deve ser armazenada, o tamanho e o 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 ao tipo t e zero retorna a primeira mensagem da fila.

Essas funções são definidas em include / linux / msg.he implementadas em ipc / msg.c

Existem limitações quanto ao tamanho de uma mensagem (máximo), 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 defaults são definidos em msg.h .

Coisas da fila de mensagens System V incrivelmente antigas, explicadas aqui .

Fila de mensagens POSIX

O padrão POSIX define um mecanismo da fila de mensagens com base 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

Consulte ipc / mqueue.c

Exemplo

util-linux fornece alguns programas para analisar e modificar filas de mensagens e a especificação POSIX fornece alguns exemplos em 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 ipcsou com um 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 está vazia novamente.

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

$ ipcrm -q 65536
abanar
fonte
A mensagem (tipo e texto) é clonada / copiada e a cópia é colocada na fila de mensagens do sistema?
trusktr 16/05
muito bem colocado. Obrigado por esta explicação incrível.
precisa saber é o seguinte