2013-02-08 85 views
0

我寫了下面的代碼來獲取事件排序的使用並行線程和互斥的理解。 函數創建其關聯到功能func1的FUNC2兩個線程。函數func1檢查值爲的計數並有條件地等待func2發信號通知它。函數func2遞增計數並且當計數達到50000時,它發信號func1。 然後func1的當時50000意外的輸出使用並行線程條件等待

但在實際輸出打印的計數,它是(或應是)的值,以50000沿着也正在印刷的一些其它值。我沒有得到任何理由。我認爲,當func2信號,func1喚醒並從pthread_cond_wait語句後面執行,因此它應該只打印50000.請指出我錯在哪裏以及應該更改哪些內容以獲取正確的輸出?

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


pthread_mutex_t evmutex; 
pthread_cond_t evcond; 

char a; 
int count; 
int N = 50000; 

void *func1() 
{ 
    while(1) 
    { 
     pthread_mutex_lock(&evmutex); 
     if(count < N) 
     { 
      pthread_cond_wait(&evcond,&evmutex); 
      printf("%d\n",count); 
      count = 0; 
     } 
     pthread_mutex_unlock(&evmutex); 


    } 
} 


void *func2() 
{ 
    while(1) 
    { 
     pthread_mutex_lock(&evmutex); 
     count++; 
     if(count == N) 
     { 
      pthread_cond_signal(&evcond); 
     } 
     pthread_mutex_unlock(&evmutex); 


    } 
} 

int main() 
{ 
    pthread_t ptd1,ptd2; 

    pthread_mutex_init(&evmutex,NULL); 
    pthread_cond_init(&evcond,NULL); 
    count = 0; 
    pthread_create(&ptd1,NULL,func1,NULL); 
    pthread_create(&ptd2,NULL,func2,NULL); 


    pthread_exit(NULL); 
    pthread_mutex_destroy(&evmutex); 
    pthread_cond_destroy(&evcond); 

    return 0; 
} 

回答

0

pthread_cond_wait()某些實現從虛假的喚醒,慘了,正因爲如此,它是常見的做法是使用while (cond) { pthread_cond_wait(...); }循環來解決這個問題。

我發現這個問題的一個很好的解釋,並導致這裏:Why does pthread_cond_wait have spurious wakeups?

+0

謝謝,但同時也給予同樣的結果。 – 2013-02-08 23:47:13

1

你不與製片人,FUNC2()同步,並告訴它要等到消費者,func1的(),已處理條件。

沒有任何來自信令的條件停止生產,再獲取該互斥,並且再次遞增計數器。 pthread_cond_signal並不意味着你的製作者會停下來等待消費者進行處理。 這意味着生產者可能會在您的消費者被安排並喚醒以打印當前數字之前多次遞增計數器。

你需要添加另一個條件變量,生產者等待它的計數器遞增到N之後,並有消費者信號,當它已經處理了櫃檯。

除此之外,你需要處理虛假喚醒其他的答案中提到。

+0

您也可以爲第二個同步點使用屏障而不是第二個條件變量。 – caf 2013-02-11 09:18:37