2013-02-17 132 views
3

我有以下代碼:並行線程和併發

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

#define LOOPS 10000 

void *run(void *arg) 
{ 
    int id = strtol(arg,NULL,0); 
    int i; 
    for(i=0; i<LOOPS; i++) 
    { 
     printf("In %d.\n",id); 
    } 
} 

int main() 
{ 
    pthread_t p1,p2; 
    void *res; 

    pthread_create(&p1,NULL,run,"1"); 
    pthread_create(&p2,NULL,run,"2"); 
    pthread_join(p1,&res); 
    pthread_join(p2,&res); 
    return 0; 
} 

當運行此,無論是字符串「在1」顯示10000次連續然後「以2」連續或反之亦然顯示10000次。這些琴絃是不是應該交替出現,而不是像這樣連續顯示?

回答

8

在線程調度器交錯的順序是不確定的(...好它,但僅僅從調度的/內核的點)。你不應該對訂單做出假設。

這種情況你會發現任何一個線程都可以在調度器之前完成他們的整個工作 - >搶佔它並​​允許另一個線程運行。

+1

+1對於寫得很好的簡單說明 – LihO 2013-02-17 18:12:31

2

調度程序運行在時隙過程。時間段足夠大,可以有效但足夠小以給出同時執行的錯覺。

在多核CPU上,這是在操作系統內核級別實現實際上將並行執行的線程。

在此之上,輸出有時緩衝,因爲它需要大約相同數量的處理能力做一個大的寫,因爲它需要做一個小寫。當輸出到交互式終端設備時,緩衝在大多數系統上被禁用,但現在環境的細節開始變得非常重要。

對於要交錯的輸出,它必須是無緩衝的,並且可以在多核或非常細粒度的調度程序上運行,並且只是因爲您生成了一行輸出而願意執行昂貴的上下文切換。如果是多內核,則通過庫和內核的執行路徑必須在三個內核上巧妙地平衡。這可能永遠不會發生。

畢竟,要創建一個在一個時間和一個總是會準備好之前,其他運行。

2

其他兩個答案都是正確的,但我想補充一點:

兩個輸出交錯。它們不是每隔一行或兩行交錯,而更可能是數千行。當每個線程被賦予一個時間量時,它具有輸出線的時間爲的數千個線。由於您只在每個線程上打印10k行,因此在其他人開始之前,有時間完成其工作。

嘗試用一個無限循環替換您for循環,並看看會發生什麼。