Jak*_*yer 9 c python posix mqueue
我正在使用一个包含posix实时扩展的python模块来获取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)
Run Code Online (Sandbox Code Playgroud)
这将在报告之前创建大约10 mq 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
Run Code Online (Sandbox Code Playgroud)
即使对于特权用户,它仍然只能创建大约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;
}
Run Code Online (Sandbox Code Playgroud)
(编译gcc -lrt test.c)但这只能让我一次打开20 mq.实际上我想一次开几百也许一千.
有人有任何想法或建议吗?
编辑:更好的C版本错误检查.仍然最大化.
该参数fs.mqueue.queues_max仅是系统中允许的全局消息队列数.您达到的限制是每个进程的消息队列数.因为mq_open说错误代码:
[EMFILE]此进程当前正在使用太多的消息队列描述符或文件描述符.
通常,您应该能够读取(一集),每个进程的限制使用getrlimit/ setrlimit.手册页rlimit说:
RLIMIT_MSGQUEUE(自Linux 2.6.8起)
指定可以为POSIX消息队列分配的调用进程的实际用户ID的字节数限制.对mq_open(3)强制执行此限制.根据以下公式,用户创建的每个消息队列都会根据此限制计数(直到删除):
Run Code Online (Sandbox Code Playgroud)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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
790 次 |
| 最近记录: |