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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:20:46