Odpowiedzi:
Jądro Linux (2.6) implementuje dwie kolejki komunikatów:
(raczej „listy komunikatów”, ponieważ implementacja odbywa się za pomocą listy połączonej, która nie jest ściśle zgodna z zasadą FIFO)
Komunikaty IPC systemu V.
Kolejka komunikatów z systemu V.
Proces może wywołać, msgsnd()
aby wysłać wiadomość. Musi przekazać identyfikator IPC kolejki komunikatów odbierających, rozmiar wiadomości i strukturę wiadomości, w tym typ wiadomości i tekst.
Z drugiej strony proces msgrcv()
odbiera komunikat, przekazując identyfikator IPC kolejki komunikatów, gdzie wiadomość powinna zostać zapisana, rozmiar i wartość t .
t określa komunikat zwrócony z kolejki, wartość dodatnia oznacza, że zwracany jest pierwszy komunikat o typie równym t , wartość ujemna zwraca ostatni komunikat równy typowi t, a zero zwraca pierwszy komunikat w kolejce.
Funkcje te są zdefiniowane w include / linux / msg.h i zaimplementowane w ipc / msg.c
Istnieją ograniczenia dotyczące rozmiaru wiadomości (maks.), Całkowitej liczby wiadomości (mni) i całkowitego rozmiaru wszystkich wiadomości w kolejce (mnb):
$ sysctl kernel.msg{max,mni,mnb}
kernel.msgmax = 8192
kernel.msgmni = 1655
kernel.msgmnb = 16384
Wyjście powyżej jest z systemu Ubuntu 10.10, wartości domyślne określone są w msg.h .
Więcej niewiarygodnie stary System V kolejka komunikatów rzeczy wyjaśnione tutaj .
Kolejka wiadomości POSIX
Standard POSIX definiuje mechanizm kolejki komunikatów oparty na kolejce komunikatów IPC Systemu V, rozszerzając ją o niektóre funkcje:
Zobacz ipc / mqueue.c
Przykład
util-linux
udostępnia niektóre programy do analizy i modyfikacji kolejek komunikatów, a specyfikacja POSIX podaje kilka przykładów C:
Utwórz kolejkę wiadomości za pomocą ipcmk
; generalnie zrobiłbyś to, wywołując funkcje C, takie jak ftok()
i msgget()
:
$ ipcmk -Q
Pozwala zobaczyć, co się stało przy użyciu ipcs
lub z cat /proc/sysvipc/msg
:
$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x33ec1686 65536 user 644 0 0
Teraz zapełnij kolejkę kilkoma wiadomościami:
$ 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
Ponownie, generalnie nie kodujesz msqid w kodzie.
$ 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
A druga strona, która otrzyma wiadomości:
$ 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
Zobacz co się dzieje:
$ 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
Po dwóch otrzymaniach kolejka jest ponownie pusta.
Usuń go później, określając key ( -Q
) lub msqid ( -q
):
$ ipcrm -q 65536