C语言使用mq_send、mq_receive实现消息队列无输出问题求助
问题排查与修复方案
现存问题
- 缺少系统调用错误校验:所有
mq_open、mq_send、mq_receive调用未判断返回值,任意一步执行失败都会导致逻辑中断但无任何提示,这是你看不到输出的核心原因。 - 接收缓冲区长度不符合POSIX消息队列规范:
mq_receive的第三个参数必须大于等于队列配置的单条消息最大长度(mq_msgsize),多数系统默认的mq_msgsize为8192字节,你定义的SIZE=1024远小于默认值,会直接导致mq_receive调用失败。 - 发送消息无字符串结束符:调用
mq_send时仅传入strlen(str_w)作为长度,该值不包含C字符串末尾的\0结束符,接收端直接用printf("%s")打印会出现乱码甚至段错误。 - 未清理残留队列:如果之前运行过错误版本的代码,会在系统中遗留属性异常的同名消息队列,重复运行也会导致逻辑异常。
修复后代码
#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <mqueue.h> #include <sys/types.h> #include <sys/wait.h> #include <errno.h> #define Q "/queue" #define SIZE 8192 int main(){ // 提前清理可能残留的旧队列,避免属性冲突 mq_unlink(Q); mqd_t qd_r = mq_open(Q, O_CREAT|O_RDONLY, 0660, NULL); if (qd_r == (mqd_t)-1) { perror("父进程mq_open失败"); exit(1); } pid_t pid = fork(); // 子进程:发送消息 if(pid == 0){ char str_w[] = "ciaoooo"; mqd_t qd_w = mq_open(Q, O_WRONLY, 0660, NULL); if (qd_w == (mqd_t)-1) { perror("子进程mq_open失败"); exit(1); } // 发送长度+1,把字符串结束符'\0'一起发送 if (mq_send(qd_w, (const char*)str_w, strlen(str_w)+1, 0) == -1) { perror("mq_send失败"); exit(1); } mq_close(qd_w); exit(0); }else{ // 父进程:接收消息 wait(NULL); char* str_r = malloc(sizeof(char)*SIZE); if (!str_r) { perror("malloc失败"); exit(1); } ssize_t recv_len = mq_receive(qd_r, str_r, SIZE, NULL); if (recv_len == -1) { perror("mq_receive失败"); exit(1); } printf("%s \n", str_r); free(str_r); mq_close(qd_r); mq_unlink(Q); return 0; } }
编译运行注意事项
编译时需要链接POSIX消息队列对应的librt库,编译命令如下:gcc 你的代码文件名.c -o mq_test -lrt
如果运行仍报错,可以先手动清理系统残留的消息队列:rm /dev/mqueue/queue
内容的提问来源于stack exchange,提问作者Matteo Stromieri
相关产品推荐
相关产品推荐

