Linux下wait(&val)系统调用程序输出解析求助
我来帮你彻底搞懂这段代码的执行逻辑和输出结果~
代码执行流程拆解
咱们一步步走这段代码的执行路径,因为fork()会创建一个独立的子进程,父、子进程会各自走不同的执行分支:
1. 初始与fork分支
父进程一开始把val设为5,然后调用fork():
- 在父进程中,
fork()返回子进程的PID(非0值),所以会进入if分支执行wait(&val)——这时候父进程会暂停,一直等到子进程结束才会继续。 - 在子进程中,
fork()返回0,所以直接跳过wait(&val),往下执行后续代码。
2. 子进程的执行逻辑
子进程的地址空间是父进程的完整副本,所以它的val初始值也是5:
- 执行
val++,val变成6。 - 调用
printf("%d\n", val),输出6。 return val,子进程以退出码6的状态正常结束。
3. 父进程的后续执行
子进程结束后,父进程的wait(&val)会被唤醒,这时候wait()会把子进程的终止状态写入val变量:
- Linux系统中,进程正常退出时,终止状态的存储规则是:高8位存退出码,低8位为0(表示是正常退出,没有收到终止信号)。子进程的退出码是6,所以写入
val的值是6 << 8 = 1536(也就是6×256)。 - 父进程接着执行
val++,把val从1536变成1537。 - 调用
printf("%d\n", val),输出1537。 - 最后
return val,父进程退出。
为什么输出是6和1537?
- 子进程先执行完成(因为父进程在
wait处等待),所以控制台先输出6。 - 父进程等待子进程结束后,
val被wait修改为子进程的终止状态值,再加1后输出1537。
补充:正确解析wait返回值的方式
如果想从wait(&val)中拿到子进程的真实退出码,应该用系统提供的专用宏,而不是直接用val的值:
WIFEXITED(val):判断子进程是否正常退出。WEXITSTATUS(val):如果是正常退出,提取出真正的退出码(也就是咱们例子中的6)。
比如可以修改父进程的代码:
if (fork()) { wait(&val); if (WIFEXITED(val)) { printf("子进程真实退出码:%d\n", WEXITSTATUS(val)); } }
这样就能正确拿到子进程的退出码6,而不是1536啦。
内容的提问来源于stack exchange,提问作者Huzaifa Jalil
相关产品推荐
相关产品推荐

