Подтвердить что ты не робот

Настройка размера очереди сообщений в системе V на Mac OSX

В настоящее время я использую очереди сообщений System V на Mac OSX, и у меня возникают проблемы с установкой размера очереди на значение, превышающее 2048 байт. Ниже приведен пример компиляции test.c:

#include <stdio.h>
#include <sys/msg.h>
#include <stdlib.h>

int main() {
  // get a message queue id
  int id = msgget(IPC_PRIVATE,IPC_CREAT|0600);
  if (-1 == id)
      exit(1);

  // get message queue data structure
  struct msqid_ds buf;
  if (-1 == msgctl(id, IPC_STAT, &buf))
      exit(1);
  printf("size is %lu bytes\n", buf.msg_qbytes);

  // set new buffer size
  buf.msg_qbytes = 2750;
  printf("setting size to %lu bytes\n", buf.msg_qbytes);
  if (-1 == msgctl(id, IPC_SET, &buf))
      exit(1);

  // check updated message queue data structure
  if (-1 == msgctl(id, IPC_STAT, &buf))
      exit(1);
  printf("size is %lu bytes\n", buf.msg_qbytes);
}

Скомпилировать с помощью:

clang -Wall -pedantic -o test test.c

И запустите с помощью:

sudo ./test

Примечание. Вы выполнили приведенный выше код с помощью sudo, чтобы убедиться в успешности вызовов msgcntl.

Вывод этого фрагмента программы:

size is 2048 bytes
setting size to 2750 bytes
size is 2048 bytes

Почему размер очереди не изменяется?

EDIT: Выходной сигнал ipcs -Q показывает:

IPC status from <running system> as of Tue Dec  1 10:06:39 PST 2015
msginfo:
    msgmax:  16384  (max characters in a message)
    msgmni:     40  (# of message queues)
    msgmnb:   2048  (max characters in a message queue)
    msgtql:     40  (max # of messages in system)
    msgssz:      8  (size of a message segment)
    msgseg:   2048  (# of message segments in system)

Можно ли сделать msgmnb больше, или я застрял?

4b9b3361

Ответ 1

Кажется, что OS X не позволяет увеличить размер очереди сообщений. Реализация системы V является старой и не документирована вообще. Мне также показалось странным, что определение MSGMNB, MSGMAX отсутствует в сообщении .h, тогда как вы можете найти его в Linux и другой реализации Unix.

Я также нашел это:

OS X - худшая из партии. Каждая очередь ограничена 2048 байтами и OS X молча игнорирует попытки увеличить это (как и FreeBSD). Чтобы добавить оскорбление к травме, похоже, нет никакого способа увеличить это ограничить перекомпиляцию ядра. Я предполагаю, что это основано на лимит очереди сообщений Darwin. (http://semanchuk.com/philip/sysv_ipc/)

Документ был обновлен в сентябре 2014 года и подтверждает сообщение в списке рассылки apple:

http://lists.apple.com/archives/unix-porting/2008/Jan/msg00033.html

Указано @Mark Setchell в комментарии.

Кроме того, недавняя реализация Ruby Wrapper не поддерживается в OS X, поскольку автор утверждает, что:

Сообщения обрабатываются ядром вашего компьютера. Не все ядра поддерживают очередь сообщений POSIX, особенно пример Дарвин (OS X). Дарвин внедряет старый API IPC System V. (https://github.com/Sirupsen/posix-mqueue)

В Интернете есть другие источники (в основном старые), которые указывают, что нет другого способа перекомпиляции ядра для увеличения пределов очереди сообщений.

UPDATE: позиция Apple заключается в том, чтобы препятствовать использованию System V IPC здесь:

Поддерживаются некоторые примитивы System V, но их использование не рекомендуется в пользу эквивалентов POSIX.

Боковое предложение, добавьте:  msgctl(id, IPC_RMID, NULL); в конце тестового кода кто-то (например, я, вздох!) мог забыть, что каждая очередь должна быть закрыта.

Ответ 2

У меня возникли проблемы с поиском документации для Mac, но POSIX говорит, что когда очередь сообщений создается через msgget(), ее "msg_qbytes устанавливается равным системному пределу." Страница руководства BSD для msgget() говорит то же самое, что и ближайший родственник OS X. Для того, что стоит, Linux man-страницы кажутся универсальными, чтобы согласиться.

Это все согласуется с тем, что если ваш размер начальной очереди не достаточно велик, вы получаете доступ. Вы можете (возможно) сжать его, но вы не сможете вырастить его выше своего начального значения.

Ответ 3

справочная страница для msgctl()

поле, в котором изменяется код, - это текущее количество байтов в очереди, а не максимальное количество байтов в очереди.

Предложите посмотреть: msglen_t msg_qbytes, которое является максимальным количеством байтов, разрешенных в очереди.