2016-06-09 26 views
0

我在閱讀關於fork函數以及它如何創建新進程。下面的程序運行正常,並打印here十六倍,但是,我無法理解的執行流程:瞭解POSIX - fork()

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <limits.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <pthread.h> 

int main() 
{ 
    int i; 
    for (i = 0; i < 4; i++) { // line no. 12 
     fork();    // line no. 13 
    } 
    printf("%s\n", "here"); 
    return 0; 
} 

在我看來,有兩種方式這個程序可以被看作是:

第一種方法:fork()總共被稱爲四次。如果我用四次調用fork()函數替換循環,事情似乎落空了,我明白爲什麼here打印2^4次。

第二種方法:fork()產生一個新的進程,從它被調用的地方開始,每個子進程都有自己的局部變量。所以,在行號後。 13,每個子進程都會看到循環的結尾(}),並且它們會轉到第1行。 12.因爲,所有這些子進程都有自己的局部變量i設置爲0(也許i被設置爲一些垃圾值?),他們都再次分叉。再次對於這些子進程,其本地變量i設置爲0.這應該導致fork bomb

我當然錯過了我的第二種方法可能有人請幫忙嗎?

謝謝。

回答

3

你的第二種方法是不正確的。因爲fork()之後子進程繼承當前i。每次調用0時都不會調用fork(),也不會有垃圾值。所以,你的代碼不能有叉形炸彈。它是一個局部變量的事實是無關緊要的。 fork()克隆幾乎所有的東西,子過程與其父項相同,除了POSIX手冊中指出的某些事項。

我會減少循環計數,以2爲便於解釋,並承擔所有fork()通話成功:

for (i = 0; i < 2; i++) { 
     fork(); 
    } 
    printf("%s\n", "here"); 

1)當i=0fork()被執行,有兩個進程了。稱他們爲P1和P2。

2)現在,每個P1和P2處理繼續,其中i = 0的迴路,並遞增i爲1。for循環條件爲真,那麼它們中的每產生另一個兩道工序和在總4.打電話給他們P1A & P1b和P2a & P2b。現在所有4個進程都有i = 1並將其增加到2(因爲它們繼續循環)。

3)現在,所有4個進程的值爲i爲2,並且for循環條件在所有這些中都爲false,並且「here」將被打印4次(每個進程一個)。

如果有幫助,您可以將for循環轉換爲while循環,以及如何i得到由過程從每個fork()返回增量可能成爲多一點明確:

i = 0; 
    while(i < 2) { 
     fork(); 
     i++; 
    } 
    printf("%s\n", "here"); 
+0

精彩講解,謝謝。 – babon

0

你的第一種方法是對。
這是一個相當無聊的答案,所以我會給你所有的技術細節。

fork叫,幾件事情發生:

  • 一個新的進程創建(「孩子」)
  • 父的堆被複制,並分配給了孩子。
  • 子級的堆棧指針設置爲父級的堆棧指針。
  • 孩子的PID(進程ID)返回給父級。
  • 零返回給孩子申報

變量裏面函數存儲在堆棧,因此在相同的值開始,但共享。
聲明的變量以外函數(在頂層)不在堆棧中,所以在父/子之間共享。

(有些事情還是不重複;看到man fork以獲取更多信息。)

所以,當你運行你的代碼:

what happens     # of processes 
1. the parent forks.    2 
2. the parent and it's child fork. 4 
3. everyone forks     8 
4. everyone forks     16 
5. everyone prints "here".   16 

您十六個過程結束,字'這裏'十六次。

基本上,

if(fork() != 0) { 
    parent_stuff(); 
} else { 
    child_stuff(); 
} 
+0

當你說'在函數外部聲明的變量是共享的'時,你的意思是說,任何由子進程寫入該變量對父進程都是可見的?如果你的意思是這樣,我認爲你錯了。感謝您的回覆。 – babon

+0

我99%確定它是正確的,但是'man fork'並沒有提到它。 – Blacksilver

+0

那麼你會如何解釋這裏列出的程序的輸出:http://hastebin.com/owedavelob.xml – babon