系统中的POSIX队列数量

发布于 2025-01-28 07:13:46 字数 1490 浏览 2 评论 0原文

我在文档和现实之间存在奇怪的差异。 MAN 7 MQ_OVERVIEW状态:

 /proc/sys/fs/mqueue/queues_max
         该文件可用于查看和更改全系统范围的限制
         关于可以创建的消息队列的数量。
         queues_max的默认值为256。
 

我检查了我的系统(实际Linux和WSL2相同的结果) - queues_max中的数字确实是256。

但是简单的压力测试表明,系统中的总排队总数为9。 这是我使用的测试代码:

#include <stdio.h>
#include <mqueue.h>

int main(int argc, char **argv) {
    for(int i=0; i<100; i++) {
        char name[32];
        snprintf(name, sizeof(name), "/%s%d", argv[1], i);

        mqd_t mqd = mq_open(name, O_RDONLY | O_NONBLOCK | O_CREAT, S_IRUSR, NULL);
        if (mqd == -1) {
            printf("Opening %s failed with: %m\n", name);
            return 1;
        }
        printf("Opened %s, mqd=%d\n", name, mqd);

        if (mq_close(mqd)) {
            printf("Failed to close %s: %m\n", name);
            return 1;
        }

        /* this removes the queue from the system
        if (mq_unlink(name)) {
            printf("Failed to delete %s: %m\n", name);
            return 1;
        }*/
    }
    return 0;
}

执行为:

$ gcc mqtest.c -lrt
$ a.out a
Opened /a0, mqd=3
Opened /a1, mqd=3
Opened /a2, mqd=3
Opened /a3, mqd=3
Opened /a4, mqd=3
Opened /a5, mqd=3
Opened /a6, mqd=3
Opened /a7, mqd=3
Opened /a8, mqd=3
Opening /a9 failed with: Too many open files
$ a.out b
Opening /b0 failed with: Too many open files
$

因此,数字9不是每个程序,而是每个系统。

我想念什么?

I have a strange discrepancy between documentation and reality.
The man 7 mq_overview states:

  /proc/sys/fs/mqueue/queues_max
         This  file  can  be  used  to  view and change the system-wide limit
         on the number of message queues that can be created.
         The default value for queues_max is 256.

I checked, on my systems (real Linux and WSL2 same results) - the number in the queues_max is indeed 256.

But a simple stress test shows that total number of queues in the system is 9.
Here is a code for testing I used:

#include <stdio.h>
#include <mqueue.h>

int main(int argc, char **argv) {
    for(int i=0; i<100; i++) {
        char name[32];
        snprintf(name, sizeof(name), "/%s%d", argv[1], i);

        mqd_t mqd = mq_open(name, O_RDONLY | O_NONBLOCK | O_CREAT, S_IRUSR, NULL);
        if (mqd == -1) {
            printf("Opening %s failed with: %m\n", name);
            return 1;
        }
        printf("Opened %s, mqd=%d\n", name, mqd);

        if (mq_close(mqd)) {
            printf("Failed to close %s: %m\n", name);
            return 1;
        }

        /* this removes the queue from the system
        if (mq_unlink(name)) {
            printf("Failed to delete %s: %m\n", name);
            return 1;
        }*/
    }
    return 0;
}

executed as:

$ gcc mqtest.c -lrt
$ a.out a
Opened /a0, mqd=3
Opened /a1, mqd=3
Opened /a2, mqd=3
Opened /a3, mqd=3
Opened /a4, mqd=3
Opened /a5, mqd=3
Opened /a6, mqd=3
Opened /a7, mqd=3
Opened /a8, mqd=3
Opening /a9 failed with: Too many open files
$ a.out b
Opening /b0 failed with: Too many open files
$

So the number 9 is not per-process, it is per-system.

What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

薄荷→糖丶微凉 2025-02-04 07:13:46

一旦我发布了一个问题,我就有了Enepiphany ...

OS给出的错误消息是错误的。问题不是许多文件,而是有内存。 POSIX队列基于共享内存(由Mqueue模块拥有) - 应用程序在系统范围内的内存中创建一个命名段,而All MQ_Send()/MQ_receive()只需阅读此段即可。但是所有队列使用的全部内存都是有限的。

因此,误差应为enomem(12),而不是emfile(errno = 24)。

通过引入打开队列的限制来测试:

    struct mq_attr attribs;
    attribs.mq_maxmsg  = 10;
    attribs.mq_msgsize = 1024;
    attribs.mq_flags   = 0;

现在,我可以打开72个队列。请注意,它不是每个程序(如文档中所述),而是每个系统。

As soon as I posted a question, I had en epiphany...

The error message given by the OS is wrong. The problem is not with a number of files, but with a memory. The POSIX queue is based on a shared memory (owned by the mqueue module) - application creates a named segment in a system-wide memory and all mq_send()/mq_receive() just read this segment. But total memory used by all queues is limited.

So instead of EMFILE (errno=24), the error should be ENOMEM (12).

Tested by introducing a limit on the opened queue:

    struct mq_attr attribs;
    attribs.mq_maxmsg  = 10;
    attribs.mq_msgsize = 1024;
    attribs.mq_flags   = 0;

Now, I can open 72 queues in total. Please note, it is not per-process (as stated in documentation), but per-system.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文