fork問題的經典理解

來源:互聯網
上載者:User

 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次!!!!

(精要)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.