C语言使用fork()配合共享内存时所有子进程输出值相同问题求助
问题排查与修复方案
你的代码存在2处核心逻辑错误,直接导致运行结果不符合预期:
- 打印时机顺序错误
你在父进程的默认分支中先执行display()打印结果,再调用wait()等待子进程结束。此时所有子进程尚未完成drive()函数里的累加计算,打印的是未完成计算的脏数据,甚至可能子进程还没开始写入共享内存。
修复方案:将display()调用移到wait()循环之后,等所有子进程完全执行完毕退出后再打印最终结果。
修改后的父进程分支代码:
default: /******** 先等待所有子进程执行完毕 *********/ for (int j = 0; j < NUMBER_OF_CARS; j++) { wait(NULL); } /******** 所有子进程退出后再打印结果 *********/ display();
- 随机数种子继承导致序列重复
你仅在父进程启动时调用了一次srand(time(NULL))初始化随机种子。fork()创建子进程时会完整复制父进程的全部内存状态,包括rand()函数的全局种子值,所有子进程生成的随机数序列完全一致,最终每个子进程累加出来的时长自然完全相同。
修复方案:在每个子进程的业务逻辑执行前,单独初始化随机种子,可以用进程ID和当前时间做异或保证种子唯一。
修改后的子进程分支代码:
case 0: // 子进程单独初始化随机种子,避免所有子进程随机序列重复 srand(time(NULL) ^ getpid()); drive(i); exit(EXIT_SUCCESS);
- (可选优化)显式初始化共享内存
虽然shmget创建的IPC_PRIVATE共享内存默认会清零,还是建议显式初始化共享内存内容,避免出现未知脏值,在shmat成功后增加初始化代码:
// 初始化所有车辆的累计时长为0 memset(shared_memory, 0, sizeof(car) * NUMBER_OF_CARS);
因为每个子进程只会修改自己对应下标的结构体数据,不存在多进程并发写同一块内存的问题,不需要额外加锁,修复以上问题后即可得到预期的互不相同的时长结果。
内容的提问来源于stack exchange,提问作者bendour
相关产品推荐
相关产品推荐

