fork问题的经典理解

 main()  
  {  
      pid_t   pid;  
      if(pid=fork()<0)  
      {  
          printf("error!");  
      }  
      else  
      {  
            if(pid==0)  
            printf("a/n");  
            else  
            printf("b/n");  
      }  
  }  
  结果是返回a,b或者b,a  
  因为fork调用将执行两次返回分别从子进程和父进程返回  
  由于父进程和子进程无关,父进程与子进程都可能先返回  
   
  在看一个程序  
   
  main()  
  {  
      pid_t   a_pid,b_fork;  
      if(a_pid=fork()<0)  
      {  
          printf("error!");  
      }  
      else  
      {  
            if(a_pid==0)  
            printf("b/n");  
            else  
            printf("a/n");  
      }  
   
      if(b_pid=fork()<0)  
      {  
          printf("error!");  
      }  
      else  
      {  
            if(b_pid==0)  
            printf("c/n");  
            else  
            printf("a/n");  
      }  
  }  
   
  如果是创建两个进程则出现结果  
  b  
  c  
  a  
  a  
  c  
  a  

事实上,理解fork()的关键在于它的返回点在哪里。fork最特殊的地方就在于他有两个甚至三个返回值,注意是同时返回两个值。其中pid=0的这个返回值用来执行子进程的代码,而大于0的一个返回值为父进程的代码块。第一次fork调用的时候生叉分为两个进程,不妨设为a父进程和b子进程。他们分别各自在第二次fork调用之前打印了b和a各一次;在第一次叉分的这两个进程中都含有  
  if(b_pid=fork()<0)  
  {  
  printf("error!");  
  }  
  else  
  {  
  if(b_pid==0)  
  printf("c/n");  
  else  
  printf("a/n");  
  }  
  }  
  这段代码。很明显,a父进程和b子进程在这段代码中又各自独立的被叉分为两个进程。这两个进程每个进程又都打印了a,c各一次。到此,在程序中总共打印三次a两次c和一次b。总共6个字母。  
  注:在第一次叉分为两个进程的时候父子进程含有完全相同的代码(第二次仍然相同),只是因为在父子进程中返回的PID的值不同,父进程代码中的PID的值大于0,子进程代码中的值等于0,从而通过if这样的分支选择语句来执行各自的任务。

 

我做如下修改

#include <unistd.h>; 
#include <sys/types.h>; 

main () 

        pid_t pid; 
        printf("fork!");    // printf("fork!n");
        pid=fork(); 

        if (pid < 0) 
                printf("error in fork!"); 
        else if (pid == 0) 
                printf("i am the child process, my process id is %dn",getpid()); 
        else 
                printf("i am the parent process, my process id is %dn",getpid()); 
}

 

结果是 
[root@localhost c]# ./a.out 
fork!i am the child process, my process id is 4286 
fork!i am the parent process, my process id is 4285

但我改成printf("fork!n");后,结果是
[root@localhost c]# ./a.out
fork! 
i am the child process, my process id is 4286 
i am the parent process, my process id is 4285

为什么只有一个fork!打印出来了?上一个为什么有2个?

我也来一下:
wujiajia 的理解有些错误,
printf("AAAAAAAA");//print 一次;   这里会print 2次
如果你将 printf("AAAAAA") 换成 printf("AAAAAAn")   那么就是只打印一次了.
主要的区别是因为有了一个 n  回车符号
这就跟Printf的缓冲机制有关了,printf某些内容时,操作系统仅仅是把该内容放到了stdout的缓冲队列里了,并没有实际的写到屏幕上
但是,只要看到有 n 则会立即刷新stdout,因此就马上能够打印了.
运行了printf("AAAAAA") 后, AAAAAA 仅仅被放到了缓冲里,再运行到fork时,缓冲里面的 AAAAAA 被子进程继承了
因此在子进程度stdout缓冲里面就也有了 AAAAAA.
所以,你最终看到的会是 AAAAAA 被printf了2次!!!!
而运行 printf("AAAAAAn")后, AAAAAA 被立即打印到了屏幕上,之后fork到的子进程里的stdout缓冲里不会有 AAAAAA 内容
因此你看到的结果会是 AAAAAA 被printf了1次!!!!

(精要)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值