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

xv6/Linux fork与waitpid进程代码分析:系统调用与输出疑问

首先咱们把这段代码格式化一下,看起来更清晰:

int main() { 
    int count = 0; 
    int pid; 
    // 初始进程P0执行这个fork,产生子进程P1
    if ( !(pid=fork())) { 
        // 只有P1(第一个fork的子进程)会进入这个分支
        while (((count<2) && (pid=fork())) ) { 
            count++; 
            printf("%d",count); 
        } 
        if(count>0) { 
            printf("%d", count); 
        } 
    } 
    // 所有fork的父进程(pid非0时)会进入这个分支
    if (pid) { 
        waitpid(pid,NULL,0); 
        count = count<<1; 
        printf("%d", count); 
    } 
}

一、可能的输出分析

先拆解各进程的行为(记住:fork创建的子进程从fork()返回处继续执行,不是从main开头):

  1. P0(初始进程):
    • 执行fork创建P1,自己进入if(pid)分支,等待P1结束后,打印0。
  2. P1(P0的子进程):
    • 进入第一个if分支,执行while循环:
      • 第一次循环:fork创建P2,count变为1,打印1。
      • 第二次循环:fork创建P3,count变为2,打印2。
    • 退出循环后,因为count>0,打印2。
    • 进入if(pid)分支,等待P3结束后,count左移1位变为4,打印4。
  3. P2(P1的子进程):
    • 从fork返回时pid=0,while条件不成立,退出循环;count=0,不打印任何内容,直接结束。
  4. P3(P1的子进程):
    • 从fork返回时pid=0,while条件不成立;count=1>0,打印1,然后结束。

调度器可以任意调度,但受waitpid的约束:

  • P1必须等P3结束才能打印4
  • P0必须等P1结束才能打印0
  • P1内部的1、2、2是顺序打印的

所以可能的输出只有两种:

  • 122140:P1先打完1、2、2,P3再打1,接着P1打4,最后P0打0
  • 121240:P1打完1、2后,P3打1,P1再打2、4,最后P0打0

二、系统调用总次数统计

系统调用包括fork和waitpid两类:

  1. fork调用:只有父进程会发起fork系统调用,总共3次:
    • P0调用1次(创建P1)
    • P1调用2次(创建P2、P3)
  2. waitpid调用:只有pid非0的父进程会调用,总共2次:
    • P0调用1次(等待P1)
    • P1调用1次(等待P3)

加起来总共有 3+2=5次 系统调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:49:59