2010-01-28 63 views
8

我不理解這個程序的輸出:ç叉處理全局變量

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

int i = 0; 

int main() 
{ 
    while(i<3) 
    { 
     fork(); 

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

輸出是:

0 
1 
2 
2 
1 
2 
0 
1 
2 
2 
2 
1 
2 
2 

可以請別人告訴我,我應該如何在解決這個問題爲了充分理解爲什麼我得到這個輸出?

+2

你還沒有告訴我們你不喜歡這件事。 – bmargulies 2010-01-28 22:15:01

+0

我不喜歡,因爲我不明白什麼時候我們會增加父進程或子進程中的fork。通常,如果我們想在子進程中增加,我們可以這樣做(fork()== 0)++ i;但是當我們這樣做時,我會在中間有點失落! – Bruno 2010-01-28 22:20:12

+1

按照答案:孩子增加孩子,父母增加父母,從來沒有兩個孩子會。 – bmargulies 2010-01-29 01:13:44

回答

24

叉將製作一個過程的副本。過程的獨立副本。所以,如果一個全局變量在你分叉的時候包含3個變量,那麼這個過程的每個副本都會得到它們自己的3.如果它們修改了,它們的修改是完全獨立的。

3

如果您想在併發編程過程中創建一個線程,請嘗試使用pthreads。你想要的功能是pthread_create和pthread_join以後整理。

事情是這樣的:

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


int i = 0; 

void *threadFunc(void *arg) 
{ 
    printf("%d\n",i); 
} 

int main() 
{ 
    int j = 0; 
    int returnValue = 0; 
    pthread_t* myThread = (pthread_t*) calloc(3, sizeof(pthread_t));; 

    while(i < 3) 
    { 

     returnValue = pthread_create(&myThread[i], NULL, threadFunc, NULL); 
     printf("main thread: %d\n",i); 
     i++; 

    } 


    for(j = 0; j < 3; j++) 
    { 
     pthread_join(myThread[j], NULL); 

    } 

    return 0; 
} 

但也許不是,這取決於你的實際需要。

5

當您fork()時,會以當前狀態創建當前進程的完整副本。這意味着你的初始化過程會在while循環的中間創建三個新進程,其中i分別爲0,1和2。它還將打印自己的值i

它的每個孩子將通過打印出i的值,遞增和循環,從fork()呼叫繼續循環。這意味着孩子0會打印0,1和2,併產生兩個新孩子,「初始」值爲i 1和2.孩子1將打印1和2併產生一個孩子,並具有「初始」值i的2.兒童2將打印2並離開循環。

如果你繼續這個推理,你會得出總共兩個0,四個1和八個2將被打印的結論。但是,由於執行順序取決於操作系統如何調度併發進程,因此不能保證打印的訂單。

16

你的代碼改成這樣,輸出應該使很多更有意義:

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

int i = 0; 

int main() 
{ 
    while (i < 3) 
    { 
     fork(); 
     printf("pid = %d, i = %d\n", getpid(), i); 
     ++i; 
    } 
    return 0; 
} 
2

這有點像......

1 (main) instance, i = 0(unforked) 
fork() > 2 instances, with i's = 0(forked), and 0(forked) 
0 output from main instance, increments its i, 2 instances with i = 1u, 0f 
main instance forks, there's 3 instances with i's 1f, 1f, 0f 
1 output from main instance, increments its i, 3 instances with i = 2u, 1f, 0f 
main instance forks, there's 4 instances with i's 2f, 2f, 1f, 0f 
2 output from main instance, increments its i, 4 instances with i = 3u, 2f, 1f, 0f 
main instance then dies, 3 instances with i = 2f, 1f, 0f 
2 output from next instance, increments its i, 3 instances with i = 3u, 1f, 0f 
next instance then dies, 2 instances with i = 1f, 0f 
1 output from next instance, increments its i to 2, 2 instances with i = 2u, 0f 

...等

的順序進程正在輸出,但未確定,所以您可能不會每次都看到完全相同的輸出,即使這樣做也不是您可以保證的。

正如其他人所說,每個進程都有自己的全局「我」,它跟蹤,它的價值僅僅是分叉過程中我的分叉值。