不能创建超过 10 个 mqueue

Cannot create more than 10 mqueues

我正在使用 python 模块包装 posix 实时扩展来获取 MessageQueues。

这是python代码

#!/usr/bin env python
import uuid
import posix_ipc
import time

def spawn():
    return posix_ipc.MessageQueue("/%s" % uuid.uuid4(), flags=posix_ipc.O_CREAT)

i = 0
while True:
    i += 1
    spawn()
    print(i)

这将在报告前创建大约 10 个 mqs OSError: This process already has the maximum number of files open

我查看了 mq 限制和 rlimit 并检查它们是否都设置得非常高。例如。

fs.file-max = 2097152
fs.mqueue.msg_max = 1000
fs.mqueue.queues_max = 1000

即使是特权用户,它也只会创建大约 10 个队列。

直接使用实时扩展的等价C如下

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <mqueue.h>

#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char **argv)
{
    mqd_t mq;
    struct mq_attr attr;
    char buffer[1024 + 1];
    int must_stop = 0;

    /* initialize the queue attributes */
    attr.mq_flags = 0;
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = 1024;
    attr.mq_curmsgs = 0;

    /* create the message queue */
    int count = 0;
    char name[5];
    while (1) {
        sprintf(name, "/%d", count);
        mq = mq_open(name, O_CREAT | O_RDONLY, 0644, &attr);
        if (mq == (mqd_t) -1)
            handle_error("mq_open");
        count++;

    }
    return 0;
}

(用gcc -lrt test.c编译) 但这只能让我一次打开 20 个 mq。实际上,我希望一次打开几百个或一千个。

有人有什么想法或建议吗?

编辑:C 版本中更好的错误检查。还是满分。

参数fs.mqueue.queues_max只是系统允许的全局消息队列数。您达到的限制是每个进程的消息队列数。因为 mq_open 说到错误代码:

[EMFILE] Too many message queue descriptors or file descriptors are currently in use by this process.

您通常应该能够读取(一组)每个进程限制 getrlimit/setrlimitrlimit 的手册页说:

RLIMIT_MSGQUEUE (Since Linux 2.6.8)

Specifies the limit on the number of bytes that can be allocated for POSIX message queues for the real user ID of the calling process. This limit is enforced for mq_open(3). Each message queue that the user creates counts (until it is removed) against this limit according to the formula:

bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) +
        attr.mq_maxmsg * attr.mq_msgsize

where attr is the mq_attr structure specified as the fourth argument to mq_open(3).

The first addend in the formula, which includes sizeof(struct msg_msg *) (4 bytes on Linux/i386), ensures that the user cannot create an unlimited number of zero-length messages (such messages nevertheless each consume some system memory for bookkeeping overhead).

您也可以尝试读取该值并乘以您需要的值:

struct rlimit limit;

getrlimit(RLIMIT_MSGQUEUE, &limit);
limit.rlim_cur *= 20;
limit.rlim_max *= 20;
setrlimit(RLIMIT_MSGQUEUE, &limit);