2012-05-18 52 views
1

我讀了一本書,這給下一個代碼:的Posix /線程加入

void *printme(void *id) { 
    int *i; 
    i = (int *)id; 
    printf("Hi. I'm thread %d\n", *i); 
    return NULL; 
} 

void main() { 
    int i, vals[4]; 
    pthread_t tids[4]; 
    void *retval; 
    for (i = 0; i < 4; i++) { 
     vals[i] = i; 
     pthread_create(tids+i, NULL, printme, vals+i); 
    } 
    for (i = 0; i < 4; i++) { 
     printf("Trying to join with tid%d\n", i); 
     pthread_join(tids[i], &retval); 
     printf("Joined with tid%d\n", i); 
    } 
} 

和未來可能的輸出:

Trying to join with tid0 
Hi. I'm thread 0 
Hi. I'm thread 1 
Hi. I'm thread 2 
Hi. I'm thread 3 
Joined with tid0 
Trying to join with tid1 
Joined with tid1 
Trying to join with tid2 
Joined with tid2 
Trying to join with tid3 
Joined with tid3 

而且我不明白這怎麼可能。我們從主線程開始,創建4個線程:tids[0]... tids[3]。然後,我們暫停執行(通過加入指令):主線程將等待tids[0]停止執行,tids[0]將等待到tids[1]等等。

所以輸出應該是:

Hi. I'm thread 0 
Hi. I'm thread 1 
Hi. I'm thread 2 
Hi. I'm thread 3 
Trying to join with tid0 
Trying to join with tid1 
Joined with tid0 
Trying to join with tid2 
Joined with tid1 
Trying to join with tid3 
Joined with tid2 
Joined with tid3 

我覺得我不明白真正的基本的東西。謝謝。

回答

2

我想你錯過的是pthread_createfork完全不同。創建的線程從提供的函數開始(在這種情況下爲printme),並在該函數返回時立即退出。因此,新創建的線程都不會到達第二個for循環。

+0

線程有另一個執行空間,他們只是執行該函數,他們不會期望到達第二個循環,他們的執行將只是printme。他們無法處理任何訂單,所以在這種情況下,所有線程都會被創建,並且控制權仍在主線程中。當連接被調用時,它會進入睡眠狀態,任何線程都可以工作。它返回並釋放本身的連接。 – Mustafa

2

當您創建新線程pthread_create時,線程#1和主線程並行工作。主要進入phtread_join的下一條指令並掛起,直到線程#1結束。這就是爲什麼你試圖加入tid0,然後你好我是線程#1。

請注意,主線程將按照指定的順序連接子線程。這意味着當線程#1,線程#2和線程#3和線程1需要10秒執行時,線程2需要6秒執行,線程3需要7秒執行,那麼第一次連接將在10秒,然後在幾毫秒內你應該有下一個連接,因爲所有其他線程應該完成他們的工作。