系统中的POSIX队列数量
我在文档和现实之间存在奇怪的差异。 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一旦我发布了一个问题,我就有了Enepiphany ...
OS给出的错误消息是错误的。问题不是许多文件,而是有内存。 POSIX队列基于共享内存(由Mqueue模块拥有) - 应用程序在系统范围内的内存中创建一个命名段,而All MQ_Send()/MQ_receive()只需阅读此段即可。但是所有队列使用的全部内存都是有限的。
因此,误差应为enomem(12),而不是emfile(errno = 24)。
通过引入打开队列的限制来测试:
现在,我可以打开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:
Now, I can open 72 queues in total. Please note, it is not per-process (as stated in documentation), but per-system.