2010-09-16 187 views
4

雖然我已經完成了很多其他類型的編程,但我對C編程確實很陌生。這個C代碼是做什麼的?

我想知道如果有人能向我解釋爲什麼這個計劃產出10

#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include <stdlib.h> 

int value = 10; 

int main() 
{ 
    pid_t pid; 

    pid = fork(); 
    if(pid == 0){ 
    value += 10; 
    } 
    else if(pid > 0){ 
     wait(NULL); 
     printf("parent: value = %d\n", value); //Line A 
     exit(0); 
    } 
} 

我知道輸出是「父:值= 10」。有人知道爲什麼

謝謝!

+0

謝謝你!完全理解現在正在發生什麼! – kralco626 2010-09-16 20:31:18

+0

這是一些編程課程中常見的功課題,它的功課不是嗎? – ldog 2010-09-16 20:34:20

+0

如果您對答案滿意,那麼標記最佳答案是個好習慣。這將獎勵海報,並讓其他人知道問題已經解決。 – 2010-09-16 20:49:50

回答

4

關於叉():

  • 如果fork()的返回負值, 創建一個子進程是 不成功。
  • 如果fork()將0返回給新創建的子進程 。
  • 如果fork()返回一個正值,則子進程的進程ID爲 ,爲父進程的 。

所以在你區分它綁定到返回一個大於0的數&因此值將保持10 &將被打印。

+0

真棒回答。我正在試圖圍繞這個包裹我的頭。所以父進程得到一個大於0的數字,因此進入else部分並打印。子進程得到0.這個子進程是做什麼的?它是否創建了一個從當前行執行的新過程?或從代碼的開始? – kralco626 2010-09-16 20:24:46

+0

@ kralco626它是父進程的副本,從相同的點/狀態執行:http://man.cx/fork%282%29 – Bruno 2010-09-16 20:30:18

16

fork創建兩個進程(「父」和「子」)。在你的例子中,每個進程都有不同的pid值。子進程的pid爲0.父進程具有子進程的操作系統pid的pid(由操作系統分配)。

在您的示例中,每個進程在其內存中都有自己的value。他們做不是共享內存(就像你認爲他們應該由你的問題所示)。如果你改變一個進程(if的第一部分),它不會反映在第二個進程中(if的第二部分)。

編輯:解釋了pid的值。

+3

由fork返回的pid對於子進程是0,對於父進程是大於0。 – 2010-09-16 20:19:37

+0

爲什麼兒童進程PID爲0?爲什麼父進程不是0,每個孩子都從那裏增加? – kralco626 2010-09-16 20:22:03

+0

@ kralco626:'man fork'說:「成功時,子進程的PID返回父進程,並且0返回給子進程。」 – Bruno 2010-09-16 20:24:44

0

fork()創建一個新的進程:它在兩個不同的上下文中有兩個返回值,所以兩個路徑都在你的if語句中運行。條件主要用於確定在fork後運行哪個進程。

+0

但只有一條輸出線。你能帶我看看發生了什麼事嗎?爲什麼父級和子級進程不創建和輸出語句? – kralco626 2010-09-16 20:20:49

+0

因爲在孩子中,fork返回0.在父代中,fork返回孩子的pid。 – 2010-09-16 20:22:20

+0

哈哈你現在我明白了。進程從fork()調用點分離。子進程的值爲0,父進程的值大於0.我想我明白了! – kralco626 2010-09-16 20:28:19

2

那麼,fork催生了一個新的過程。它或多或少會複製當前進程,並且新代碼(子代)和舊代碼(父代)在代碼中的同一點繼續進行。但是這裏有一個顯着的區別(我們感興趣):對於孩子,fork返回0.對於父親,它返回孩子的進程ID。

所以if(pid ==0)部分是真實的孩子。孩子簡單地添加10到他的value,然後退出,因爲沒有進一步的代碼。

else部分對於父級是正確的(除非極少數情況下fork返回-1錯誤)。父母簡單地wait s爲孩子退出。但是孩子已經修改了自己的副本value,父母的一個仍然沒有被觸動,這就是爲什麼你得到「10」的輸出。然後父母也退出。

0

當您撥打fork時,它會創建一個過程副本,使副本'program counter s在其代碼部分處於相同位置。因此,當這些副本中的任何一個恢復執行時,兩者都將完成對fork的呼叫。

所以他們都應該執行相同的。

但是,fork在子進程中返回0,並在父進程中返回子進程的pid

這解釋了if(pid==0)部分背後的魔咒。

所以當子進程更改value的值時,它實際上改變了它自己的副本(記住:進程已被複制,因此數據部分也被複制了)。

同時,父進程及其古老的value價值,這是10

孩子改變其副本value即使在和死亡,父母的副本仍然是10

0

叉執行系統調用將創建一個新的進程作爲現有(父)進程的子進程。父對象和子對象都繼續在fork語句後面的行中執行,但子進程被賦予父對象地址空間的精確副本。

fork系統調用會將新創建的進程的進程ID返回給父進程,並將其返回給子進程,因此在此代碼中,子進程會增加自己的值變量副本,並且父進程會打印出自己的副本。

你會經常看到fork後面跟着一個exec在子內部,這樣它就可以用另一個程序代替它自己了。