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开头):
- P0(初始进程):
- 执行fork创建P1,自己进入
if(pid)分支,等待P1结束后,打印0。
- 执行fork创建P1,自己进入
- P1(P0的子进程):
- 进入第一个if分支,执行while循环:
- 第一次循环:fork创建P2,count变为1,打印
1。 - 第二次循环:fork创建P3,count变为2,打印
2。
- 第一次循环:fork创建P2,count变为1,打印
- 退出循环后,因为count>0,打印
2。 - 进入
if(pid)分支,等待P3结束后,count左移1位变为4,打印4。
- 进入第一个if分支,执行while循环:
- P2(P1的子进程):
- 从fork返回时pid=0,while条件不成立,退出循环;count=0,不打印任何内容,直接结束。
- P3(P1的子进程):
- 从fork返回时pid=0,while条件不成立;count=1>0,打印
1,然后结束。
- 从fork返回时pid=0,while条件不成立;count=1>0,打印
调度器可以任意调度,但受waitpid的约束:
- P1必须等P3结束才能打印
4 - P0必须等P1结束才能打印
0 - P1内部的
1、2、2是顺序打印的
所以可能的输出只有两种:
122140:P1先打完1、2、2,P3再打1,接着P1打4,最后P0打0121240:P1打完1、2后,P3打1,P1再打2、4,最后P0打0
二、系统调用总次数统计
系统调用包括fork和waitpid两类:
- fork调用:只有父进程会发起fork系统调用,总共3次:
- P0调用1次(创建P1)
- P1调用2次(创建P2、P3)
- waitpid调用:只有pid非0的父进程会调用,总共2次:
- P0调用1次(等待P1)
- P1调用1次(等待P3)
加起来总共有 3+2=5次 系统调用。
内容的提问来源于stack exchange,提问作者Aleka
相关产品推荐
相关产品推荐

