You need to enable JavaScript to run this app. Linux消息队列mq_receive返回Message too long且属性未生效问题
优惠活动
大模型
产品
解决方案
定价
更多

Linux消息队列mq_receive返回Message too long且属性未生效问题

问题原因分析

1. 自定义属性未生效的核心原因

POSIX消息队列的mq_open函数传入的struct mq_attr参数,仅当本次调用通过O_CREAT新建队列时才会生效。如果对应名称的消息队列已经存在于系统中,O_CREAT只会打开已有队列,你传入的属性参数会被直接忽略。

Linux系统POSIX消息队列默认的mq_msgsize值就是8192字节,和你输出的结果完全匹配,说明你运行代码前系统中已经存在同名的/sp-example-server队列,直接复用了旧队列的默认属性,你自定义的256字节上限没有生效。

补充说明:POSIX消息队列是内核持久化资源,只要没有手动删除或者重启系统,之前创建的队列会一直保留,不会随程序退出自动销毁。

2. 宏定义的潜在隐患

你定义MSG_BUFFER_SIZE时没有加括号:

// 原写法有运算优先级隐患
#define MSG_BUFFER_SIZE MAX_MSG_SIZE + 10

虽然当前定义数组时计算的长度是对的(256+10=266字节),但如果后续代码中出现MSG_BUFFER_SIZE * 2这类运算,会被展开为256 + 10 * 2 = 276,和预期的266*2=532不符,建议修改为:

#define MSG_BUFFER_SIZE (MAX_MSG_SIZE + 10)

3. Message too long错误的直接原因

你当前队列实际的mq_msgsize是8192字节,但接收缓冲区in_buffer只有266字节,小于要求的最小值,不符合mq_receive的参数要求:POSIX规范要求mq_receive的第三个参数(缓冲区长度)必须大于等于队列的mq_msgsize属性,无论实际接收的消息长度是多少。

解决方案
  • 先删除系统中已存在的同名旧队列:
    可以直接执行命令 rm /dev/mqueue/sp-example-server,也可以在代码中mq_open之前先调用 mq_unlink("/sp-example-server"); 删除旧队列,再重新创建就能生效你自定义的属性。
  • 如果不需要修改队列属性,可以直接把接收缓冲区的长度调整为不小于队列实际的mq_msgsize值(当前场景开8192字节以上的缓冲区即可)。

内容的提问来源于stack exchange,提问作者xyf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 11:06:02