2012-05-23 98 views
4

我讀了一本書,給出了下面的例子:並行線程/等待(狀態)

int value=0 
int thread_func(int id) { 
    int temp; 
    temp=value+id; 
    printf("Thread%d value: %d", id, temp); 
    value=temp; 
} 

int main() { 
    int fork_id, status, i; 
    pthread_t tids[3]; 
    fork_id=fork(); 
if (fork_id == 0) { 
    for (i=1; i≤3; i++) 
     pthread_create(&tids[i-1], NULL, thread_func, i); 
     for (i=0; i≤2; i++) 
     pthread_join(tids+i, &status); 
     printf("Second process value: %d", value); 
    } 
else { 
    wait(&status); 
     printf("First process value: %d", value) 
     } 

我不明白兩兩件事: 當我讀到,該行已在printf("First process value: %d", value)是唯一的價值0. 但是爲什麼?等待(&狀態)將一直等到子進程終止。在這種情況下,只有在所有連接都完成後纔會終止。意思是,當值爲6.

其次,在行printf("Second process value: %d", value);,值可以從1到6.這也很奇怪,因爲我們有連接指令。

回答

3

的問題的答案:

  1. 的值將是在父進程0,因爲當fork發生父的地址空間被複制(連同可變value)在子​​進程。因此,雖然value在孩子中發生了變化,但這一變化並不反映在父母中,因爲它們是不同的變量。

  2. 由於沒有涉及同步,因此無法知道變量value被三個子線程更改的順序。具體來說,每個線程都有一個帶有不同值的本地temp變量,然後將其複製到全局變量value中,但無法知道線程將以何種順序覆蓋value,其中temp這裏是:value = temp;。因此,其執行價值可能會有所不同。

+0

謝謝你的回答。關於我的第二個問題:我們真的不知道三個子線程的變量值是以哪種順序變化的,但是我們可以知道,在所有三個線程完成後(因爲連接指令),我們將到達這一行。我錯過了什麼? –

+1

@Adam Sh:問題是,例如在一次執行中,第一個線程使'temp = 0 + 1',然後設置'value = 1'。然後第二個線程到達,使'temp = 1 + 2'然後設置'value = 3',最後一個線程使'temp = 3 + 3'並設置'value = 6'。在另一個可能的執行過程中,第一個線程設置'temp = 0 + 1',但是在達到'temp = value'之前,第二個線程'temp = 0 + 2'(因爲線程1沒有達到'temp = value')然後使'值= 2'。現在你可以看到最終的價值會完全不同。 – Tudor

0

因爲當你fork的時候,你會得到一個擁有自己內存的全新進程,這意味着在一個進程中變量的更改不會顯示在另一個進程中。另一方面,線程共享內存,這意味着線程化程序中變量的變化顯示在所有線程中。

0

值由子進程遞增,所以爲0。

if(fork_id == 0){ 
...... 
...... 
} 

是由產生的線程子執行父進程將顯示其價值。

和子進程有不同的內存副本。所以增加孩子的價值對父母來說並不意味着同樣的價值。

線程可以訪問全局值。