前几天,论坛上有人问了这样一个问题:
#include <sys/types.h>
#include <unistd.h>
int main
()
{ for
(int i
= 0
; i
< 3
; i
++)
{ int pid
= fork
(); if
(pid
== 0
)
{ printf
("child\n"
);
} else
{ printf
("father\n"
);
}
} return 0
;
}请问输出结果是什么?
初看,想当然认为结果是3对child
-father,只是顺序不确定,而且按照Unix环境高级编程中的说法,极端的情况下可能还会出现两个输出的内容相互夹杂的情况。
但是,在Unix测试了一下发现输出竟然有7对child
-father。为什么会这样呢?看了半天程序终于明白了这个简单的问题。其实,这个问题在写
/懂汇编的人看来是再清楚不过了,问题就出在这个for循环。
1.i
=0时,父进程进入for循环,此时由于fork的作用,产生父子两个进程
(分别记为F0
/S0
),分别输出father和child,然后,二者分别执行后续的代码,那后续的代码是什么呢
?return 0
?当然不是,由于for循环的存在,后续的代码是add指令和一条jump指令,因此,父子进程都将进入i
=1的情况;
2.i
=1时,父进程继续分成父子两个进程
(分别记为F1
/S1
),而i
=0时fork出的子进程也将分成两个进程
(分别记为FS01
/SS01
),然后所有这些进程进入i
=2;
3.
....过程于上面类似,已经不用多说了,相信一切都已经明了了,依照上面的标记方法,i
=2时将产生F2
/S2
,FS12
/SS12
,FFS012
/SFS012
,FSS012
/SSS012
.因此,最终的结果是输出7对child
/father。其对应的数学公式为:
1
+ 2
+ 4
+ ... + 2
^(n
- 1
) = 2
^n
- 1
不过话说回来,这种在for循环中使用fork的作法实在不值得推荐,研究研究尚可,实际应用恐怕会引来很多麻烦,需小心谨慎才是。
本文地址:http://com.8s8s.com/it/it32002.htm