2012-12-08 24 views
0

在此鏈接here中,在遞增函數中,條件變量在實際遞增計數(從零開始)之前發出信號。信號在遞增計數之後是否應該被調用?或者在decrement_count函數中的等待調用不會返回,直到在increment_function中釋放互斥量爲止?條件變量信號發送

pthread_mutex_t count_lock; 
pthread_cond_t count_nonzero; 
unsigned count; 

decrement_count() 
{ 
    pthread_mutex_lock(&count_lock); 
    while (count == 0) 
     pthread_cond_wait(&count_nonzero, &count_lock); 
    count = count - 1; 
    pthread_mutex_unlock(&count_lock); 
} 

increment_count() 
{ 
    pthread_mutex_lock(&count_lock); 
    if (count == 0) 
     pthread_cond_signal(&count_nonzero); 
    count = count + 1; 
    pthread_mutex_unlock(&count_lock); 
} 

回答

2

因爲互斥鎖,如果你之前或之後的信號做到這一點,因爲變量不能被讀取,直到互斥量被釋放沒關係。

+0

因此,遞減函數中的等待調用不會返回,直到條件變量發出信號並且互斥量在增量函數中解鎖爲止? – Kamal

+0

正確的是,當進入cond等待時,它釋放互斥鎖,當它再次喚醒時,它會再次鎖定互斥鎖,因爲互斥鎖被鎖定在緩存函數中,cond不會被喚醒直到其解鎖。 – goji

1

因爲Troy says,在增加counter之前發信號通知條件變量是好的,因爲這些操作都是在保持互斥體的情況下完成的。

但是,如果多個線程可以在decrement_count()中等待,此代碼確實有一個微妙的錯誤。考慮在pthread_cond_wait()中掛起兩個線程的情況,count == 0。現在,increment_count()被連續調用兩次(也許是同一個線程) - count會增加到2,因爲它應該是這樣,但條件變量只發送一次信號。這意味着等待線程只有一個被喚醒,而另一個將無限期地等待,即使counter非零。

此錯誤可以固定在幾個方面:

  • increment_count()pthread_cond_broadcast()取代pthread_cond_signal();或
  • 無條件地撥打在increment_count();或
  • 請致電pthread_cond_signal()如果countdecrement_count()遞減後不爲零。

在一般情況下,請記住,使用pthread_cond_signal()代替pthread_cond_broadcast()是一個優化的,你應該仔細分析使用時的算法是否仍然正確。