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