繁体   English   中英

在FC 18机器上,mq_open失败,错误为EMFILE

[英]On FC 18 machine mq_open fails with error no EMFILE

我试图打开一个新的消息队列,但是它失败,并显示太多打开文件(24)错误。

这是我的示例代码:

#define ALERT_Q_NAME "/alert_q_test"

mqd_t mqdes;

int main()
{
    struct mq_attr attr;

    attr.mq_flags = 0;
    attr.mq_maxmsg = 512;
    attr.mq_msgsize = 1536;

    mqdes = mq_open(ALERT_Q_NAME, O_RDONLY | O_CREAT, 0600, &attr);
    if(mqdes == (mqd_t) -1)
    {
            printf("Failed:%d(%s)\n",errno,strerror(errno));
            exit(-1);
    }
    else
    {
            printf("Passed\n");
            mq_close(mqdes);
    }
    return 0;
}

可以创建的消息队列的系统范围限制为:

$ cat / proc / sys / fs / mqueue / queues_max
256

我确定没有达到系统限制,因为我正在新安装的FC18盒子上运行此示例代码。 只是为了确认这一点,我安装了消息队列文件系统:

$ mkdir / dev / mqueue
$ mount -t mqueue none / dev / mqueue
$ ls -l / dev / mqueue
总计0
$ gcc -g -o mqueue mqueue.c -lrt
$。/ mqueue
失败:24(打开的文件太多)
$ ls -l / dev / mqueue
总计0

就像FC18一样,我无法在内核版本3.6.10和3.6.11上运行的Linux机器上创建消息队列。 虽然同一程序可以在Linux 2.6.31和Linux 3.3.4上正常运行。

好像它在某个地方坏了。 还是我在这里想念什么? 请帮忙吗?!? 谢谢!!

答案有点晚,但是:

如果打开的文件过多或最大队列大小超出限制,mq_open可能会失败,并显示errno = EMFILE。

有关大小计算的更多信息,请参见setrlimit(2)中的 RLIMIT_MSGQUEUE。

要获取当前的软/硬限制:

grep -E 'Limit|queue' /proc/self/limits

要永久更改限制,请编辑/etc/security/limits.conf并使用'su-'再次登录。

/etc/security/limits.conf:

[user] hard msgqueue unlimited
[user] soft msgqueue unlimited

另一种可能性是使用setrlimt(2)/ prlimit(2)设置软限制。 如果出于您的目的而使hardlimit变小,则需要CAP_SYS_RESOURCE。

我看到的一个问题是,即使将attr设置为NULL,默认值对于@ wr0112358上面讨论的每个进程的限制也太大。

因此我们可以很好地在

# cat /proc/sys/fs/mqueue/msg_max
128
# cat /proc/sys/fs/mqueue/msgsize_max
65536

同时超出了每个进程的限制。

# ulimit -a |grep queue
POSIX message queues     (bytes, -q) 819200

您可以用来检查的一种快速解决方案是增加ulimit:

# ulimit -q unlimited

或按照@ wr0112358的说明设置rlimit以获得更永久的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM