一段关于fork的小程序的启示

前几天,论坛上有人问了这样一个问题:
#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的作法实在不值得推荐,研究研究尚可,实际应用恐怕会引来很多麻烦,需小心谨慎才是。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值