多线程消息队列开发中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
相关产品推荐
相关产品推荐

