2017-09-24 84 views
1

我試圖確定的處理多少總數有以下代碼:計算在叉的過程總數()碼

#include <stdio.h> 
#include <unistd.h> 

int main() { 

int i = 1; 

    if (fork()) //parent process will return PID of child. 
     i++; 
    else if (fork()) //child process (becomes parent) 
      i--; 
     else //grandchild process returns 0 
      i++; 

printf("%d\n", i); 
} 

通常,用於的過程總#式是2^n其中n是分叉系統調用的數量。我很困惑,因爲這個示例涉及if/else條件語句。

我總共得到4個進程。 (從如果(fork())聲明和從elseif(fork())聲明)的2個進程的2個進程。有人可以確認這是否正確?如果沒有,請你指導我正確的方向/解釋如何計算過程的數量。這是我在確定時遇到的一些麻煩。

謝謝大家。

+1

將printf更改爲顯示'printf(「i =%d,pid =%d \ n」,i,getpid());'你將自己得到答案。或者,更好的方法是打印'getppid()'的結果,您就可以構建整個流程層次結構。 –

回答

1

關注:在if()報表進行評估true即使fork()沒有贏得成功,因爲在這種情況下,它會返回一個負數是從0true不同。

你有3個過程

第一fork()產生父進程的一個副本,即,一個孩子。現在你有2個進程。 fork()將子PID返回給父級。這使得父母的第一個if()條件爲true,子女爲false。父級增加變量i

因此,子流程在進入第二個if語句之前執行一個分支,然後被消除。叉子產生一個孩子的副本(現在成爲父母),即一個孫子。你現在有3個進程。

兒童評估else if條件true並會遞減i而孫評估false,並且將增加i。根據我的說法,如果你試圖執行你的程序,你將只能得到3個輸出(執行3個printf())。輸出的順序取決於CPU調度程序如何調度進程,這是您無法預測的。

+0

嗨@Neb這個答案讓我更容易理解。我想知道它的可視化效果如何?它只是:父母 - >孩子 - >孩子的孩子(孫子)?以下是我對可視化的看法:http://oi65.tinypic.com/ofztrr.jpg – Derek

+1

@Derek:確切地說。父執行流程進入第一個'i ++',所以它永遠不會執行第二個'fork()'。它的孩子會這樣做,並會產生孫子。你的圖是正確的。既然我幫了你,你能幫我接受我的答案嗎? – Neb

+0

嗨@Neb最後一個問題,孫子怎麼評價爲假?它不應該是真的,因爲else語句意味着fork()== 0?哪個評估對孩子是真實的?現在接受你的答案:)謝謝。 – Derek

1

,而不是你的代碼,試試這個:

#include <stdio.h> 
#include <unistd.h> 

int main() 
{ 
    int counter = 0; 

    if(fork()) 
    { 
     // should be the parent 
     fprintf(stderr, "1. process ID: %d\n", getpid()); 
     fprintf(stderr, "1. parent process ID: %d\n", getppid()); 
     ++counter; 
    } 
    else 
    if(fork()) 
    { 
     fprintf(stderr, "2. process ID: %d\n", getpid()); 
     fprintf(stderr, "2. parent process ID: %d\n", getppid()); 
     --counter; 
    } 
    else 
    { 
     fprintf(stderr, "3. process ID: %d\n", getpid()); 
     fprintf(stderr, "3. parent process ID: %d\n", getppid()); 
     ++counter; 
    } 

    printf("counter: %d\n", counter); 
} 

這裏是運行代碼的輸出:

ALP ❱ gcc temp.c 
ALP ❱ ./a.out 
1. process ID: 6672 
1. parent process ID: 3037 
counter: 1 
2. process ID: 6673 
2. parent process ID: 6672 
counter: -1 
3. process ID: 6674 
3. parent process ID: 2008 
counter: 1 
ALP ❱ ps 
    PID TTY   TIME CMD 
3037 pts/2 00:00:01 bash 
5354 pts/2 00:00:00 redshift 
6642 pts/2 00:00:00 ps 
ALP ❱ ps -e | grep 2008 
2008 ?  00:00:00 upstart 
ALP ❱ 

現在正在發生的事情是這樣的:

3037我的機器上的進程ID 2008是進程ID upstart(=照顧zombi這裏的電子處理)
6672main功能
6673的進程ID爲第一子過程及其父母是主要:6672
6674第二子過程和2008(=暴發戶)成爲其父母

雖然我不知道,但我猜你有子進程沿着主,因此共3個。由於您沒有檢查-1調用fork(2)的失敗,所以在運行代碼的其他人可能會有所不同。


注意
因爲你爲你的孩子和主要出口不wait(2)不終止它們,upstart(8)需要終止他們的照顧。

注2:
以這種方式,則不應使用fork(2)