Як реалізується черга повідомлень у ядрі Linux?


29

Мені хотілося б знати, як реалізуються черги на повідомлення в ядрі Linux.


IPC_NOWAIT ми використовуємо його лише у приймачі
Anwaar Qa

Відповіді:


41

Ядро 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

Тож повідомлення (тип і текст) клонується / копіюється, а потім ця копія потрапляє в чергу повідомлень системи?
trusktr

дуже красиво поставлений. Дякую за це дивовижне пояснення.
User9102d82
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.