2015-02-08 64 views
0
int g_ant = 0; 
void *writeloop(void *arg) 
{ 
while(g_ant < 10) 
    { 
    g_ant++; 
    usleep(rand()%10); 
    printf("%d\n", g_ant); 
    } 
exit(0); 
} 

int main(void) 
{ 
pthread_t time; 
pthread_create(&time, NULL, writeloop, NULL); 
writeloop(NULL); 
pthread_join(time, NUL); 
return 0; 
} 

嗨!我有四個問題,我認爲在類別競賽條件下......? :-)C多線程程序行爲說明

  1. 我試圖找出爲什麼g_ant的printf的,我的電腦上,開始於2和的情況下,90%繼續10,偶爾1,3-> 10輸出。我的猜測是因爲usleep可能會妨礙thread1足夠長的時間,以便在thread1到達printf之前讓thread2遞增並且printf。
  2. 難道這不會搞亂2-> 10的數字嗎?
  3. 我也在努力理解這個程序中的pthread_join函數。我的理解是它用來等待一個線程完成。它是否正在等待由pthread_create啓動的writeloop函數?
  4. 是writeloop(null)認爲是第二個線程?

回答

2
  1. g_ant++; 不是原子操作,這可能會導致未定義的行爲。您應該使用
    pthread_mutex_lock(&mutex);pthread_mutex_unlock(&mutex); 之所以它90%的時間開始於2是因爲線程time進入功能,增加g_ant,睡本身。操作系統往往會把它從CPU中拿走,並在那裏放入另一個沒有睡着的線程,在你的情況下,這是你的主線程,它再次增加1次運行usleep。現在g_ant的值爲2,線程time恢復並打印2並將其遞增爲3.主線程恢復並打印3並再次遞增它,這保持了切換,這就是爲什麼大多數時候您會看到2到10的數字。

希望它已經夠清楚了,應該回答2.問題。

  1. pthread_join確保其他線程在您的主線程退出程序之前完成其工作。

  2. nope它不被視爲第二個線程,它運行主線程上的功能。

    希望它有幫助。

2
  • 主線程被認爲是另一個線程。在添加互斥體之前,下列內容可能會幫助您瞭解發生了什麼事(假設您需要下一步操作 )。通常,您不會從線程退出()整個進程 - 它永遠不會加入到主線程中。
  • #include <pthread.h> 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <unistd.h> 
    
    int g_ant = 0; 
    
    void *writeloop(void *arg) 
    { 
        while(g_ant < 10) 
        { 
         g_ant++; 
         usleep(rand() % 10); 
         printf("thread: %u global: %d\n", (unsigned int)pthread_self(), g_ant); 
        } 
        return NULL; 
    } 
    
    int main(void) 
    { 
        pthread_t t; 
        pthread_create(&t, NULL, writeloop, NULL); 
        writeloop(NULL); 
        pthread_join(t, NULL); 
        printf("Joined\n"); 
        return 0; 
    } 
    
    +0

    你說得對互斥體的一部分。感謝這個例子:) – Thomas 2015-02-09 00:24:09