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

fork()创建父子进程后消息队列msgrcv永久阻塞问题排查

代码问题分析与修复

核心阻塞原因

  • 父子进程的地址空间相互独立,子进程中执行的msg.mtype = 1赋值操作,仅会修改子进程地址空间内的msg变量副本,父进程地址空间中的msg结构体的mtype字段没有初始化,是随机的脏值。
  • 父进程调用msgsnd(msgid2, &msg, sizeof(msg), 0)发送消息时,发出的消息的mtype不符合子进程msgrcv指定接收的1的要求,子进程匹配不到符合条件的消息,就会永久阻塞在打印3之前的msgrcv调用行。

其他潜在问题

  • 消息收发的长度参数不符合System V消息队列的接口要求:msgsnd和msgrcv的第三个参数是除mtype字段之外的消息正文长度,代码中直接传入整个结构体的大小,相当于多计算了mtype的长度,可能引发消息截断、内存读写越界问题。
  • 消息队列删除时机错误:子进程发送完第二个msgPing后直接删除两个消息队列,可能导致父进程还没来得及读取最后一个msgPing,队列就被销毁,引发后续异常。

修复方案

  1. 在父进程发送msg前主动初始化msg.mtype = 1,或者直接在fork操作之前就完成所有全局消息结构体的初始化,保证父子进程拿到的初始值一致。
  2. 修正收发长度参数:msgPing的收发长度改为sizeof(msgPing) - sizeof(long),msg的收发长度改为sizeof(msg) - sizeof(long)。
  3. 把消息队列销毁的逻辑移到父进程所有操作执行完成之后,避免提前销毁队列导致消息丢失。

核心修改参考代码

// fork前初始化全局变量,保证父子进程初始值一致
msg.mtype = 1;
msgPing.mtype = 1;

if(fork() == 0) {
    // 子进程
    int msgid1;
    int msgid2;
    msgid1 = msgget(MSG_KEY1, 0666 | IPC_CREAT);
    msgid2 = msgget(MSG_KEY2, 0666 | IPC_CREAT);

    printf("1 - started, sending msgPing\n");
    // 修正发送长度
    msgsnd(msgid1, &msgPing, sizeof(msgPing) - sizeof(long), 0);
    // 修正接收长度
    msgrcv(msgid2, &msg, sizeof(msg) - sizeof(long), 1, 0);

    printf("3 - msg received, sending msgPing\n");
    msgsnd(msgid1, &msgPing, sizeof(msgPing) - sizeof(long), 0);

    // 子进程不再提前销毁队列
    return 0;
}

// 父进程
sleep(1);
int msgid1;
int msgid2;
msgid1 = msgget(MSG_KEY1, 0666 | IPC_CREAT);
msgid2 = msgget(MSG_KEY2, 0666 | IPC_CREAT);

msgrcv(msgid1, &msgPing, sizeof(msgPing) - sizeof(long), 1, 0);
printf("2 - msgPing received, sending msg\n");

msgsnd(msgid2, &msg, sizeof(msg) - sizeof(long), 0);
msgrcv(msgid1, &msgPing, sizeof(msgPing) - sizeof(long), 1, 0);

printf("4 - msgPing received, finished\n");

// 父进程最后销毁队列
msgctl(msgid1, IPC_RMID, 0);
msgctl(msgid2, IPC_RMID, 0);
return 0;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 19:45:09