Linux下C++调用mq_open返回-1的调试方法咨询
调试Linux下mq_open返回-1的问题
先修正代码里的明显错误
- 结构体拼写错误:你写的
struct mq_arrt是错误的,正确应为struct mq_attr;成员mq_magsize同样拼写错误,正确名称是mq_msgsize。 - 消息队列名未初始化:
char temp[32];是未赋值的局部变量,直接传给mq_unlink和mq_open会导致操作随机的无效队列名,必然出错。消息队列名必须以/开头,比如"/test_mq"。
调试步骤
第一步:打印具体错误原因
mq_open返回-1时会设置errno,调用perror或strerror(errno)即可获取错误详情,代码示例:#include <string.h> #include <errno.h> #include <stdio.h> // ... 你的业务代码 ... msgQptr = mq_open(temp, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR, &msQAtt); if (msgQptr == -1) { perror("mq_open failed"); // 也可以用:printf("Error detail: %s\n", strerror(errno)); }常见错误类型:
EINVAL(参数非法,比如队列名格式错误、maxmsg/msgsize超过系统限制)、ENOSPC(系统消息队列资源耗尽)、EACCES(权限不足)等。第二步:验证参数合法性
- 队列名格式:必须以
/开头,且中间不能包含其他/,比如"/my_msg_queue"合法,"my_queue"或"/a/b"均不合法。 - 检查系统资源限制:
执行cat /proc/sys/fs/mqueue/msg_max和cat /proc/sys/fs/mqueue/msgsize_max查看系统默认限制。示例2的MaxMsgs=2400大概率超过默认的msg_max(多数系统默认值为1024甚至更低),MaxMsgLength=4136若超过msgsize_max也会导致失败。
若需要调整限制,可通过root权限修改上述文件,或用ulimit临时调整(比如ulimit -q 65536调整消息队列总容量)。
- 队列名格式:必须以
第三步:排查mq_unlink的影响
创建新队列无需提前调用mq_unlink,除非你确认目标队列已存在且需要删除。但如果队列名无效,mq_unlink本身也会失败,不过该失败不会影响后续mq_open,核心还是要确保队列名合法。
修正后的代码示例
#include <mqueue.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <stdint.h> typedef mqd_t eoMQHndlT; int main() { int32_t MaxMsgs = 10; int32_t MaxMsgLength = 1232; // 示例2参数:int32_t MaxMsgs = 2400; int32_t MaxMsgLength = 4136; eoMQHndlT msgQptr = -1; char temp[32] = "/test_msg_queue"; // 初始化合法队列名 struct mq_attr msQAtt; msQAtt.mq_flags = 0; msQAtt.mq_maxmsg = MaxMsgs; msQAtt.mq_msgsize = MaxMsgLength; msQAtt.mq_curmsgs = 0; msgQptr = mq_open(temp, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR, &msQAtt); if (msgQptr == -1) { perror("mq_open failed"); return 1; } // 后续业务操作... mq_close(msgQptr); mq_unlink(temp); return 0; }
内容的提问来源于stack exchange,提问作者jkafernando
相关产品推荐
相关产品推荐

