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

Posted

技术标签:

【中文标题】在 Mac OSX 上设置 System V 消息队列大小【英文标题】:Setting System V message queue size on Mac OSX 【发布时间】:2016-03-04 18:30:39 【问题描述】:

我目前在 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 调用成功。

这个程序sn-p的输出是:

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 可以变大,还是我被卡住了?

【问题讨论】:

尝试运行ipcs -Q 看看是否有最大尺寸。 @MarkSetchell - 我用ipcs -Q 的输出更新了问题。 我从来没有在 OSX 上尝试过这个,我不知道它是否有效或可能会导致问题,但我猜你会做类似sysctl -w kernel.msgmnb=2000000 @MarkSetchell - 是的。不幸的是,sysctl -A | grep msgmnb 什么也没返回。我没有看到任何与 System V 消息队列相关的内容:( @user3629249 - 这是 Mac OSX 的问题。 System V 消息队列在 Linux 上运行良好。 【参考方案1】:

似乎 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); 在测试代​​码结束时,有人(像我一样,叹气!)可能会忘记每个队列都必须关闭。

【讨论】:

遗憾的是,Mac 上没有与 System V 消息队列等效的 POSIX,因为根本不支持 Posix 队列。 @dinkelk 是的,但奇怪的是,正如您所看到的,这就是开发人员页面中报告的内容【参考方案2】:

我在查找特定于 Mac 的文档时遇到了麻烦,但 POSIX says 指出,当通过 msgget() 创建消息队列时,其“msg_qbytes 应设置为等于系统限制”。 msgget() 的 BSD 手册页也这么说,这是 OS X 最接近的亲戚。对于它的价值,Linux 手册页似乎普遍同意。

这完全一致地表明,如果您的初始队列大小不够大,那么您就会被淹没。你可以(也许)缩小它,但你不能让它超过它的初始值。

【讨论】:

【参考方案3】:

msgctl() 的手册页

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

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

【讨论】:

如果你看我的代码,它实际上是在改变msg_qbytes

以上是关于在 Mac OSX 上设置 System V 消息队列大小的主要内容,如果未能解决你的问题,请参考以下文章

Eclipse mac osx:启动失败,找不到二进制文件

MAC OSX Xcode 9.2 链接器命令失败,退出代码为 1(使用 -v 查看调用)

无法在 Mac OSX 上设置 $GOPATH

MAC OSX Xcode 9.2链接器命令失败,退出代码为1(使用-v查看调用)

TinkerTool System for Mac(系统设备维护工具)免激活

csharp Windows,Linux和mac osx上的System.Environment.OSVersion