C程序中fork调用导致父进程输出递增重复的问题咨询
程序输出行为解析
核心逻辑拆解
1. fork()的返回值与循环执行流程
fork()系统调用会创建子进程:- 父进程返回子进程PID(非0值,视为逻辑真)。
- 子进程返回0(视为逻辑假)。
- 循环条件
fork() && i < 5利用了逻辑与的短路求值特性:- 父进程中
fork()返回真,会继续判断i < 5。只要i < 5成立,就进入循环体:等待子进程退出、打印一个Yo!、i自增1。 - 子进程中
fork()返回假,逻辑与的第二个表达式i < 5不会执行,直接跳出循环,打印当前继承的i值后退出。
- 父进程中
2. 变量i的独立性
每次fork()后,子进程会复制父进程的整个地址空间,包括变量i的当前值:
- 第一个子进程继承父进程初始的
i=0,打印0后退出。 - 父进程等待它退出后,
i变为1,再fork出第二个子进程,该子进程继承i=1,打印1后退出。 - 以此类推,子进程打印的
i依次为0、1、2、3、4,父进程每次循环后i递增1。
3. 输出缓冲区的影响
C语言中printf默认是行缓冲模式,没有换行符\n时,输出内容会暂存在进程的用户缓冲区中,直到进程退出时才会一次性刷新到标准输出:
- 父进程在5次循环中打印的
Yo!会一直累积在缓冲区里,直到父进程最终退出时,才会将这5个Yo!和最后打印的5一起输出。 - 当父进程的
i变为5时,循环条件先执行fork()(此时i<5不成立,循环终止),这次fork出的子进程继承i=5,退出时打印5,这就是输出末尾的第二个5。
最终输出对应关系
拆解输出内容:
0→ 第一个子进程的输出Yo!→ 父进程第一次循环后的输出(缓冲区暂存)1→ 第二个子进程的输出Yo!Yo!→ 父进程前两次循环的Yo!累积输出2→ 第三个子进程的输出Yo!Yo!Yo!→ 父进程前三次循环的Yo!累积输出- ...以此类推,直到父进程退出时输出
5Yo!Yo!Yo!Yo!Yo!,加上最后一个子进程的5,就得到了完整输出。
内容的提问来源于stack exchange,提问作者Badja
相关产品推荐
相关产品推荐

