C语言fork()进程创建问题:为何代码仅链式创建子进程而非全量fork
问题说明
存在一段调用fork()的C语言代码,对其运行逻辑有疑问,代码如下:
int hijo,i,N; int main(int argc, char*argv[]){ N=atoi(argv[1]); for(i=0;i<N;i++) if((hijo=fork())>0)break; }
核心疑问:为什么这段程序只会在上一轮新创建的子进程基础上创建单个子进程,而不是每次执行fork()前,让所有已存在的进程都执行fork()生成新进程?
逻辑解析
要搞懂这个行为,首先得明确fork()的返回值规则:
- 调用
fork()后,原进程(父进程)会拿到新创建子进程的PID,这个值恒大于0 - 新生成的子进程会拿到返回值0
- 调用出错时才会返回负值
再对应代码里的判断逻辑就能找到原因:每次fork()执行完成后,只要当前进程是父进程(拿到的返回值>0),就会直接执行break跳出整个for循环,完全不会参与下一轮的fork()调用。
我们可以拿N=3的场景逐轮拆解运行流程:
- 初始状态只有1个主进程,i=0时进入循环调用
fork()- 主进程拿到子进程PID>0,触发
break直接退出循环,后续再也不会执行fork() - 新生成的第1个子进程拿到返回值0,不满足if判断条件,不会执行
break,i自增到1后进入下一轮循环
- 主进程拿到子进程PID>0,触发
- i=1时,整个程序里只有刚才生成的第1个子进程还在循环中,由它调用
fork()- 第1个子进程(本轮fork的父进程)拿到返回值>0,触发
break退出循环 - 新生成的第2个子进程拿到返回值0,不触发
break,i自增到2后进入下一轮循环
- 第1个子进程(本轮fork的父进程)拿到返回值>0,触发
- i=2时,只有第2个子进程留在循环中,由它调用
fork()- 第2个子进程(本轮fork的父进程)拿到返回值>0,触发
break退出循环 - 新生成的第3个子进程拿到返回值0,不触发
break,i自增到3后不满足i<N的循环条件,自动退出循环
- 第2个子进程(本轮fork的父进程)拿到返回值>0,触发
整个流程走下来,每一轮永远只有上一轮刚生成的子进程留在循环里执行下一次fork(),之前所有的父进程都已经通过break退出了循环,自然不会出现所有现存进程同时执行fork()、进程数指数增长的情况。如果去掉代码里的break语句,才会出现每轮所有现存进程都fork、最终生成2^N个进程的效果。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

