You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程消息队列开发中mq_receive无报错导致程序崩溃问题求助

问题原因排查
  • mq_getattr 传参错误:mq_getattr 第二个参数要求传入 struct mq_attr 类型的指针,你的代码直接传了结构体变量 chars 没有取地址,会触发内存非法访问,直接导致段错误崩溃,错误信号会直接终止进程,不会走后续的 mq_receive 错误判断逻辑。
  • mq_receive 第一个参数使用了未定义变量:全局队列的变量名是 global_queue,但调用 mq_receive 时传的是未定义的 queue,会拿到垃圾值作为消息队列描述符,触发系统调用异常崩溃。
  • 线程创建参数错误:main 函数中循环变量是 count,但 pthread_create 传入的线程ID数组下标是未初始化的 k,会导致线程创建逻辑异常,甚至直接修改非法内存地址导致崩溃。
  • 缺少返回值校验逻辑:mq_open、mq_getattr、pthread_create 都没有校验返回值,一旦某个前置调用失败,后续逻辑都会触发不可预期的错误。
  • 打印缓冲未刷新:你使用的 printf 没有加换行符,默认行缓冲模式下内容不会立即输出到终端,可能出现程序崩溃前日志没打印的假象,建议日志后加 \n 或者调用 fflush(stdout) 强制刷新。
修复后的参考代码
#include <mqueue.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

mqd_t global_queue;
pthread_t tArr[10];

void* process(void* arg) {
    struct mq_attr attr;
    // 校验getattr调用返回值,属性只需获取一次无需放在循环内
    if (mq_getattr(global_queue, &attr) != 0) {
        perror("mq_getattr failed");
        return NULL;
    }
    // 用堆内存代替栈上可变长度数组,避免栈溢出
    char* recBuf = malloc(attr.mq_msgsize);
    if (recBuf == NULL) {
        perror("malloc recv buffer failed");
        return NULL;
    }
    unsigned int prio = 0;
    ssize_t recvLen;

    while (1) {
        printf("Before recv\n");
        recvLen = mq_receive(global_queue, recBuf, attr.mq_msgsize, &prio);
        if (recvLen < 0) {
            perror("mq_receive failed");
            continue;
        }
        printf("After recv, received %zd bytes\n", recvLen);
        // 此处补充业务处理逻辑
    }

    free(recBuf);
    return NULL;
}

int main()
{
    global_queue = mq_open("/queue_name", O_CREAT | O_RDWR, 0777, NULL);
    // 校验队列打开结果
    if (global_queue == (mqd_t)-1) {
        perror("mq_open failed");
        return 1;
    }
    for (int count = 0; count < 10; count++)
    {
        // 使用正确的循环变量作为数组下标
        if (pthread_create(&tArr[count], NULL, process, NULL) != 0) {
            perror("pthread_create failed");
            return 1;
        }
    }
    // 等待所有线程执行完毕
    for (int count = 0; count < 10; count++) {
        pthread_join(tArr[count], NULL);
    }
    mq_close(global_queue);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 13:24:07