fork()与wait()使用中的变量作用域问题及C++代码调试
问题描述
我正在学习wait和fork函数,尝试输出父进程与子进程的Sum值,但父进程中的Sum似乎被重新初始化为0;同时我不确定C++中wait函数的实现方式,因为网上相关资源多为C语言。
我的代码
#include <sys/wait.h> #include <unistd.h> #include <iostream> int Sum = 0; void printout() { int id = fork(); if(id!=0) { wait(NULL); } if(id == 0) { Sum += 2; } if(id!= 0) { Sum += 3; } } int main() { printout(); std::cout<<Sum<<std::endl; }
预期输出
5
实际输出
2 3
问题分析与解决
1. 输出不符合预期的原因
fork()会创建一个独立的子进程,它是父进程的内存副本,但两者的内存空间完全隔离——父进程和子进程的Sum是两个毫无关联的变量:
- 子进程中执行
Sum +=2,此时子进程的Sum为2,随后子进程执行main里的输出语句,打印2。 - 父进程调用
wait(NULL)等待子进程结束后,执行Sum +=3,父进程的Sum初始值是0,加3后变为3,接着打印3。
所以你会看到两行独立的输出,而非累加后的5。
2. 实现预期输出的方法
要让父进程获取子进程的计算结果,必须使用**进程间通信(IPC)**机制。如果只是传递简单的小数值,可以用子进程的退出码(范围0-255),示例代码如下:
#include <sys/wait.h> #include <unistd.h> #include <iostream> int Sum = 0; void printout() { int id = fork(); if(id == 0) { // 子进程计算结果,通过exit传递 int child_val = 2; exit(child_val); } else { int status; wait(&status); // 解析子进程的退出码,拿到计算结果 int child_result = WEXITSTATUS(status); Sum += child_result + 3; } } int main() { printout(); std::cout<<Sum<<std::endl; }
这段代码中,父进程获取子进程返回的2,加上自己的3,最终输出5。
3. C++中wait函数的使用说明
wait是POSIX标准的系统调用,C++并未重新实现,而是直接兼容C语言的接口。使用时只需包含头文件<sys/wait.h>,用法和C语言完全一致:
wait(NULL):等待任意子进程终止,不获取其退出状态。wait(&status):等待任意子进程终止,并将退出状态存入status变量,之后可以用WEXITSTATUS(status)等宏解析状态值(这些宏同样定义在<sys/wait.h>中)。
内容的提问来源于stack exchange,提问作者MasterWolfy
相关产品推荐
相关产品推荐

