无法创建命名消息队列求助:原正常代码突发报错
问题描述
之前运行正常的消息队列代码突然抛出异常:
terminate called after throwing an instance of 'std::runtime_error' what(): Unable to create named message queue
报错代码如下:
void VMGR::initialize_mq() { int errsv; queue_attr.mq_flags = 0; queue_attr.mq_maxmsg = 10; queue_attr.mq_msgsize = api::msg_sz; queue_attr.mq_curmsgs = 0; mq_unlink (api::nm_mqueue); mq_close(queue); queue = mq_open( api::nm_mqueue, O_RDWR | O_CREAT | O_EXCL|O_NONBLOCK, IO_FILE_PERMISSIONS, &queue_attr ); if (queue == (mqd_t)-1) { errsv = errno; throw std::runtime_error( std::string( "Unable to create named message queue" ) ); } std::cout<< "initialize_mq works"<< std::endl; return; }
已检查/dev/mqueue确认无对应文件描述符,但问题仍未解决。
补充信息
执行ulimit -a输出:
core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 1030932 max locked memory (kbytes, -l) 65536 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 1030932 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
当前系统消息队列标识符列表:
Data7aa vmgr_proc135978 vmgr_proc40571 vmgr_proc55053 Data7bb vmgr_proc136146 vmgr_proc42152 vmgr_proc56557 Data7cc vmgr_proc136536 vmgr_proc43732 vmgr_proc9190 Data7dd vmgr_proc16914 vmgr_proc45247 vmgr_proc93026 Data7ee vmgr_proc17107 vmgr_proc46576 vmgr_proc9362 Data7gg vmgr_proc21970 vmgr_proc47958 vmgr_proc93706 Data7hh vmgr_proc29728 vmgr_proc49422 vmgr_proc93925 hello_moto vmgr_proc31111 vmgr_proc49700 vmgr_proc94596 vmgr_proc123434 vmgr_proc32504 vmgr_proc51452 vmgr_proc9528 vmgr_proc132441 vmgr_proc35308 vmgr_proc51869 vmgr_send vmgr_proc132550 vmgr_proc39121 vmgr_proc53478
排查与解决建议
检查消息队列总容量是否超限
从ulimit -q可知,系统允许的POSIX消息队列总容量为819200字节。每个队列的占用容量为mq_maxmsg * mq_msgsize,你的代码中设为10 * api::msg_sz。当前系统中存在大量消息队列(列表中可见数十个),总容量可能已超过限制。- 解决:删除无用的消息队列(使用
mq_unlink命令),或临时调高队列容量限制(执行ulimit -q 1638400,需root权限永久修改则编辑/etc/security/limits.conf)。
- 解决:删除无用的消息队列(使用
修复代码中
mq_close与mq_unlink的顺序
代码中先执行mq_unlink再关闭队列,若queue未初始化或已失效,mq_close会触发错误;同时,若有其他进程仍在打开该队列,mq_unlink仅标记队列删除,实际资源未释放,此时用O_EXCL创建会失败。正确顺序应为:// 先关闭已打开的队列(需判断有效性) if (queue != (mqd_t)-1) { mq_close(queue); queue = (mqd_t)-1; } // 再删除队列 mq_unlink(api::nm_mqueue);添加错误详情排查
当前抛出的异常未包含具体错误码信息,建议修改throw语句,加入strerror(errsv)以明确失败原因(如EEXIST表示队列仍存在,ENOMEM表示内存/容量不足):throw std::runtime_error( std::string("Unable to create named message queue: ") + strerror(errsv) );验证权限与命名冲突
- 确认
IO_FILE_PERMISSIONS的值正确(如0664),避免因权限不足导致创建失败。 - 若错误码为
EEXIST,说明即使/dev/mqueue中无对应文件,仍有进程持有该队列的打开描述符,需找到并终止相关进程,或放弃O_EXCL标志(若允许复用队列)。
- 确认
内容的提问来源于stack exchange,提问作者Manu Chaudhary
相关产品推荐
相关产品推荐

