Как реализована очередь сообщений в ядре Linux?

30

Я хотел бы знать, как очереди сообщений реализованы в ядре Linux.

сен
источник
IPC_NOWAIT мы используем его только в приемнике
Anwaar Qa

Ответы:

41

Ядро Linux (2.6) реализует две очереди сообщений:
(скорее «списки сообщений», поскольку реализация осуществляется с использованием связанного списка, не строго следуя принципу FIFO)

Сообщения System V IPC

Очередь сообщений из системы V.

Процесс может вызвать msgsnd()отправку сообщения. Ему необходимо передать идентификатор IPC принимающей очереди сообщений, размер сообщения и структуру сообщения, включая тип сообщения и текст.

С другой стороны, процесс вызывает msgrcv()получение сообщения, передавая IPC-идентификатор очереди сообщений, где должно храниться сообщение, размер и значение t .

t определяет сообщение, возвращаемое из очереди, положительное значение означает, что возвращается первое сообщение с типом, равным t , отрицательное значение возвращает последнее сообщение, равное типу t, а ноль возвращает первое сообщение очереди.

Эти функции определены в include / linux / msg.h и реализованы в ipc / msg.c

Существуют ограничения на размер сообщения (макс.), Общее количество сообщений (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 Message Queue

Стандарт POSIX определяет механизм очереди сообщений на основе очереди сообщений System V IPC, расширяя его некоторыми функциональными возможностями:

  • Простой файловый интерфейс к приложению
  • Поддержка приоритетов сообщений
  • Поддержка асинхронного уведомления
  • Тайм-ауты для блокировки операций

Смотрите 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Затем удалите его, указав key ( ) или msqid ( -q):

$ ipcrm -q 65536
шутник
источник
Так клонируется / копируется ли сообщение (тип и текст), а затем эта копия помещается в очередь сообщений системы?
trusktr
очень красиво поставил. Спасибо за это удивительное объяснение.
User9102d82