在Mac OSX上设置System V消息队列大小

时间:2015-11-30 23:48:10

标签: c++ c macos ipc message-queue

我目前在Mac OSX上使用System V消息队列,并且无法将队列大小设置为大于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

为什么队列大小没有改变?

修改 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变得更大,还是我被困?

3 个答案:

答案 0 :(得分:5)

似乎OS X不允许增加消息队列大小。系统V实现很旧,根本没有记录。我还发现奇怪的是,在message.h中缺少定义MSGMNB,MSGMAX,而你可以在Linux和其他Unix实现中找到它。

我也发现了这个:

  

OS X是最糟糕的。每个队列限制为2048字节和   OS X默默地忽略了增加此功能的尝试(就像FreeBSD一样)。   为了增加对伤害的侮辱,似乎没有办法增加这一点   限制重新编译内核。我猜这个基于   达尔文消息队列限制。 (http://semanchuk.com/philip/sysv_ipc/

该文件于2014年9月更新,并确认了苹果邮件列表中的帖子:

  

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

@Mark Setchell在评论中指出。

此外,OS X不支持最近的Ruby Wrapper实现,因为作者声明:

  

消息由计算机内核处理。不是全部   内核支持POSIX消息队列,一个值得注意的例子就是   达尔文(OS X)。 Darwin实现了较旧的System V IPC API。   (https://github.com/Sirupsen/posix-mqueue

在网络上还有其他来源(大多数是旧的)表明除了重新编译内核以增加消息队列限制之外别无他法。

更新:Apple的立场是不鼓励使用System V IPC here

  

支持某些System V基元,但不鼓励使用它们   赞成POSIX等价物。

侧面建议,添加:  msgctl(id, IPC_RMID, NULL); 在测试代​​码的最后,有人(像我一样,感叹!)可能会忘记每个队列都必须关闭。

答案 1 :(得分:1)

我无法找到特定于Mac的文档,但是POSIX says当通过msgget()创建消息队列时,其“msg_qbytes应设置为等于系统限制。 “ msgget()的BSD手册页也是如此,这是OS X最亲近的。对于它的价值,Linux手册页似乎普遍同意。

这一切都非常一致,表明如果你的初始队列大小不够大,那么你就被软管了。你可以(可能)缩小它,但你不能超过它的初始值。

答案 2 :(得分:-1)

msgctl()

的手册页

代码正在更改的字段是队列中当前字节数,而不是队列中的最大字节数。

建议查看:msglen_t msg_qbytes这是队列中允许的最大字节数