Відповіді:
Ядро Linux (2.6) реалізує дві черги повідомлень:
(скоріше, «списки повідомлень», оскільки реалізація здійснюється за допомогою зв'язаного списку, який не суворо дотримується принципу FIFO)
Система V IPC-повідомлення
Черга повідомлень із системи V.
Процес може викликати msgsnd()
для надсилання повідомлення. Йому потрібно передати ідентифікатор IPC черги приймаючого повідомлення, розмір повідомлення та структуру повідомлення, включаючи тип та текст повідомлення.
З іншого боку, процес викликає msgrcv()
для отримання повідомлення, передаючи ідентифікатор IPC черги повідомлень, де повідомлення має зберігатися, розмір і значення t .
t вказує повідомлення, повернене з черги, позитивне значення означає, що повертається перше повідомлення з його типом, рівним t , негативне значення повертає останнє повідомлення, рівне типу t, а нульове повертає перше повідомлення черги.
Ці функції визначені в / включає / linux / msg.h та реалізовані в ipc / msg.c
Існують обмеження щодо розміру повідомлення (max), загальної кількості повідомлень (mni) та загального розміру всіх повідомлень у черзі (mnb):
$ sysctl kernel.msg{max,mni,mnb}
kernel.msgmax = 8192
kernel.msgmni = 1655
kernel.msgmnb = 16384
Вихід вище з системи Ubuntu 10.10, за замовчуванням визначені в msg.h .
Більш неймовірно старий матеріал черги повідомлень System V пояснено тут .
Черга повідомлень POSIX
Стандарт POSIX визначає механізм черги повідомлень на основі черги повідомлень IPC системи V, розширюючи його на деякі функції:
Дивіться ipc / mqueue.c
Приклад
util-linux
надає деякі програми для аналізу та зміни черг повідомлень, а специфікація POSIX дає кілька прикладів C:
Створіть чергу повідомлень за допомогою ipcmk
; як правило , ви могли б зробити це з допомогою виклику функції C , як ftok()
і msgget()
:
$ ipcmk -Q
Давайте подивимося, що сталося за допомогою ipcs
або за допомогою cat /proc/sysvipc/msg
:
$ ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x33ec1686 65536 user 644 0 0
Тепер заповніть чергу кількома повідомленнями:
$ 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
Знову ж таки, ви зазвичай не жорстко кодуєте msqid у коді.
$ 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
І інша сторона, яка отримуватиме повідомлення:
$ 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
Подивіться, що станеться:
$ 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
Після двох прийому черга знову порожня.
Видаліть його згодом, вказавши ключ ( -Q
) або msqid ( -q
):
$ ipcrm -q 65536