2011-10-31 92 views
4

編輯: 我做了一個錯誤的假設,當它們實際上開始在pthread_create上運行時,線程開始在pthread_join上運行。pthread_join()是否允許執行調用線程繼續?


我學習使用POSIX線程,和我讀過:
pthread_join() - wait for thread termination

所以,代碼樣本中,主要的退出(0)沒有達到,直到兩個啓動的線程結束。
但是在第一次調用pthread_join()之後,main繼續執行,因爲第二次調用pthread_join()實際上運行,並且中間的消息被打印。
那麼這是怎麼回事?當兩個線程還沒有完成時,main是否繼續執行?或不是嗎?
我知道這不是一種可靠的測試方法,但是無論循環多長時間,在兩個線程完成後總是會打印第二條測試消息。 (至少在我的機器上時,我試了一下)

 
void *print_message_function(void *ptr) 
{ 
    char *message = (char *) ptr; 
    for(int a = 0; a < 1000; ++a) 
     printf("%s - %i\n", message, a); 
    return NULL; 
} 
// 
int main(int argc, char *argv[]) 
{ 
    pthread_t thread1, thread2; 
    char message1[] = "Thread 1"; 
    char message2[] = "Thread 2"; 
    int iret1, iret2; 
    // 
    iret1 = pthread_create(&thread1, NULL, print_message_function, (void*) message1); 
    iret2 = pthread_create(&thread2, NULL, print_message_function, (void*) message2); 
    // 
    pthread_join(thread1, NULL); 
    printf("Let's see when is this printed...\n"); 
    pthread_join(thread2, NULL); 
    printf("And this one?...\n"); 
    // 
    printf("Thread 1 returns: %d\n",iret1); 
    printf("Thread 2 returns: %d\n",iret2); 
    exit(0); 
} 

回答

6

功能pthread_join等待線程完成,或者線程已經完成立即返回。

你的情況

所以

pthread_join(thread1, NULL); /* Start waiting for thread1. */ 
printf("Let's see when is this printed...\n"); /* Done waiting for thread1. */ 

pthread_join(thread2, NULL); /* Start waiting for thread2. */ 
printf("And this one?...\n"); /* Done waiting for thread2. */ 

但經過第一次調用在pthread_join(),主繼續執行, 因爲第二次調用在pthread_join()實際運行,而它們之間的 消息打印。

假。除非線程1已經完成,否則等待pthread_join

+0

哦對,因爲線程已經在pthread_create上啓動了。 thx – Petruza

3
pthread_join(thread1, NULL); 

主線程在這裏等待在此加入通話,直到thread1完成了工作。一旦thread1完成執行主線程將繼續並執行下一條語句printf

printf("Let's see when is this printed...\n"); 

再次,主線程將在這裏等待,直到thread2完成其工作。

pthread_join(thread2, NULL); 

一旦thread2完成了工作主線向前推進,並執行下一條語句這是printf

printf("And this one?...\n"); 

該序列將以上述方式工作。可能發生這種情況的時間太早,導致您看到的痕跡變得混亂。
另外,不要使用printf看多線程程序的行爲可以說是相當具誤導性,中的printf的順序可能並不總是指示正確的控制流,因爲它基於計時和緩衝區到標準輸出的沖洗可能不會在SASME順序發生因爲這些打印是通過線程執行的。

+0

謝謝,請參閱編輯。 – Petruza

3
pthread_join()

不返回(阻塞調用線程),直到被連接的線程已終止。如果線程已經終止,那麼它馬上返回。

在你的測試中,兩個線程都退出,所以當然你會看到從主線程打印的所有消息。當第一條消息被打印時,您知道thread1已完成;當第二個打印時,你知道thread2也是完整的。這可能會在第一次之後很快發生,因爲這兩個線程大致同時進行了相同的工作量。

2

如果第一個pthread_join立即返回,則表明第一個線程已經完成執行。輸出是什麼樣的?在「讓我們看看它何時被打印」之後,您是否看到任何「Thread 1 - n」輸出?