轉自:http://blog.sina.com.cn/s/blog_6ffd3b5c0100mc3n.html
舉一個例子( http://blog.csdn.net/KataDoc360/archive/2009/02/16/3897957.aspx): pthread_mutex_t count_lock;
pthread_cond_t count_nonzero;
unsigned count = 0;
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);
}
decrement_count和increment_count在兩個線程A和B中被調用。 正確的情況下,如果decrement_count首先運行,那麼A會被阻塞到pthread_cond_wait。隨後increment_count運行,它調用pthread_cond_signal喚醒等待條件鎖count_nonzero的A線程,但是A線程並不會馬上執行,因為它得不到互斥鎖count_lock。當B線程執行pthread_mutex_unlock之後A線程才得以繼續執行。 如果pthread_cond_signal前後沒有使用互斥鎖count_lock保護,可能的情況是這樣。A阻塞到pthread_cond_wait,然後B執行到pthread_cond_signal時候,發生了線程切換,於是A被喚醒,並且發現count依然是0,所以繼續阻塞到條件鎖count_nonzero上。然後B繼續執行,這時候儘管count=1,A永遠不會被喚醒了。這樣就發生了邏輯錯誤。 當然在這個上下文中,如果把count=count+1放在函數放在pthread_cond_signal之前變成 increment_count(){
count=count+1; if(count==0)
pthread_cond_signal(&count_nonzero);
} 這樣沒有問題。但是這種方法並不能保證所有情況下都適用。於是需要用互斥鎖保護條件鎖相關的變數。也就是說條件鎖是用來線程通訊的,但是互斥鎖是為了保護這種通訊不會產生邏輯錯誤,可以正常工作。