【问题标题】:Cannot create more than 10 mqueues不能创建超过 10 个 mqueue
【发布时间】:2017-03-13 13:25:10
【问题描述】:

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

这是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)

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

我查看了 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 个 mqs。实际上,我希望一次打开几百甚至一千个。

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

编辑:C 版本中更好的错误检查。仍然最大。

【问题讨论】:

  • C 程序错误检查不正确 — 如果 mq_open 返回 (mqd_t)-1,请检查 errno
  • @pilcrow 已修复

标签: python c posix mqueue


【解决方案1】:

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

[EMFILE] 消息队列描述符或文件描述符过多 当前正在被此进程使用。

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

RLIMIT_MSGQUEUE(自 Linux 2.6.8 起)

指定可以为调用进程的真实用户 ID 的 POSIX 消息队列分配的字节数限制。对 mq_open(3) 强制执行此限制。用户创建的每个消息队列都会根据以下公式计算(直到被删除):

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

其中 attr 是指定为 mq_open(3) 的第四个参数的 mq_attr 结构。

公式中的第一个加数,包括 sizeof(struct msg_msg *)(在 Linux/i386 上为 4 个字节),确保用户不能创建无限数量的零长度消息(尽管这样的消息每个都消耗一些系统内存用于簿记开销)。

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

struct rlimit limit;

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

【讨论】:

    猜你喜欢
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    • 2020-05-06
    相关资源
    最近更新 更多