2016-09-16 62 views
2

有人可以解釋這個程序創建多少個子進程? 答案是127,但我不明白他們是如何得到它的。分叉嵌套循環

int create(int num){ 
int i; 
for(i=0;i<num;i++) 
fork(); 
} 

int main() { 
int i; 
fork(); 
for(i=0;i<4;i++) 
create(i); 
return 0; 
} 

回答

4

這聽起來像是操作系統上的一門功課,但這是一個有趣的問題,所以我會爲你解答。首先,讓我們看看代碼如下。在功能上,它是一回事,但它會讓事情更容易消化。另外,要開始,讓我們忽略最初的fork()調用。如果它不在那裏,我們會計算它有多少,然後如果我們重新添加它,我們將擁有相同數量的進程,第二次。

int main() { 
    int i, j; 
    // fork(); 
    for (i = 0; i < 4; i++) { 
     for (j = 0; j < i; j++) { 
     fork(); 
     } 
    } 
} 

現在這部分是一個數學問題,一部分是規劃問題。首先,我們需要了解當我們撥打fork()時會發生什麼。當你創建一個子進程時,子進程會在調用該進程時繼承變量當前值的所有父變量的副本。所以這意味着現在,父母和孩子擁有完全相同的變量的副本,並具有完全相同的值,但他們可以獨立修改這些變量,並且它們不會相互影響。因此,然後在下面的簡單的例子,

int main() { 
    int i = 0, pid = fork(); 

    if (pid == 0) { 
     i = 1; 
    } 

    if (pid > 0) { 
     i = 2; 
    } 
} 

在父母的世界,i得到值2,並在孩子的世界i得到值1,而這些都是現在我們談論這樣的獨立變量父母可以擁有自己想要的東西,孩子可以擁有自己想要的東西,不會發生衝突,每個人都很開心。

現在,要回答您的問題,我們必須牢記這一點。所以讓我們先看看我們有多少進程沒有初始的fork()調用。那麼現在,父親本身會產生6個子進程。對於這些過程中的每一個,變量(i,j)將分別具有值(1,0),(2,0),(2,1),(3,0),(3,1)和(3,2) 。

所以在(3,2)處產生的最後一個孩子將退出循環,並且不會產生更多的孩子。 (3,1)產生的孩子將繼續for循環,增量j,產生另一個進程,然後兩個孩子將在(3,2)處看到(i,j),退出for循環,然後死亡。然後我們在(3,0)有另一個由父母產生的孩子。那麼現在這個孩子會繼續通過for循環,在(3,1)和(3,2)處產生一個孩子,然後死亡,然後這個在(3,1)產生的新孩子會產生另一個孩子,然後他們會死的。我想我們可以看到這開始變得非常複雜,所以我們可以用下面的圖表來表示這種情況。

enter image description here

圖形的每個頂點表示一個過程和頂點標記p是父進程。每條邊上的有序對代表在產生子進程時的值(i,j)。注意我們如何對流程進行分組。在第一組中,我們有1個過程,接下來,我們有2個,接下來的4個,然後是8個,我們現在應該看到事情進展如何。下一個組將有16個進程,下一個組將有32個進程。因此,如果我們計算了所有進程(包括父進程),則我們有64個進程。目前爲止有意義嗎?

那麼現在讓我們把最初的fork()調回來。這將導致我們剛剛描述的兩次發生的情況完全相同,這會給我們128個進程,包括父進程,這意味着我們產生了127兒童。

所以是的,一半的數學問題,一半的編程問題。讓我知道你的問題。

您可以將第一個循環改寫爲for (i = 1; i <= n; i++)。然後我很確定我們可以說一般情況下,你的父母過程會產生孩子,其中