1.如下代碼所示:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> pthread_mutex_t count_lock; pthread_cond_t count_ready; int count; void *decrement_count(void *arg) { while(1) { pthread_mutex_lock(&count_lock); printf("decrement:waiting\n"); /*等待滿足條件,期間互斥量仍然可用*/ // while (count == 0) pthread_cond_wait(&count_ready, &count_lock); printf("decrement:count = %d\n", count); if (count == 0) { printf("exit count:%d\n",count); exit(1); } count = 0; pthread_mutex_unlock(&count_lock); } pthread_exit(NULL); } void *increment_count(void *arg) { while(1) { pthread_mutex_lock(&count_lock); // printf("increment:running\n"); count = 1; /*通知線程條件已滿足*/ // printf("increment:count = %d\n", count); pthread_cond_signal(&count_ready); pthread_mutex_unlock(&count_lock); } pthread_exit(NULL); } int main() { pthread_t tid1,tid2,tid3; count=0; pthread_mutex_init(&count_lock, NULL); pthread_cond_init(&count_ready, NULL); pthread_create(&tid1, NULL, decrement_count, NULL); sleep(3); pthread_create(&tid3, NULL, decrement_count, NULL); sleep(3); pthread_create(&tid2, NULL, increment_count, NULL); /*等待decrement退出*/ pthread_join(tid2, NULL); printf("decrement quit\n"); pthread_join(tid3, NULL); pthread_join(tid1, NULL); return 0; }
g++ -g thread-cond.cpp -lpthread -o test 編譯出test程序。
然后運行,可見程序
decrement:waiting
decrement:waiting
decrement:count = 1
decrement:waiting
decrement:count = 0
exit count:0
最后退出了,為什么?
如果把tid1,tid2,tid3表示為每個線程獲得互斥鎖,那么這種情況的發生說明tid1和tid3順序獲得鎖執行了(順序也可能為tid3和tid1).
單從pthread_cond_signal函數的定義上看,如果嚴格的只發一個"信號"給指定一個線程,這種情況是絕對不可能發生的。
因為函數中pthread_cond_wait的返回代表了此線程接受到“信號”(pthread_cond_wait執行包括1.解鎖2.wait3.獲得鎖4.返回)
只有一個原因能解釋:pthread_cond_signal一次喚醒了2個wait線程,第1個獲得鎖的線程把count置為0,第2個線程發現count=0直接exit,
pthread_cond_signal發生了驚群現象。
怎么預防:
while (count == 0)
pthread_cond_wait(&count_ready, &count_lock);
在wait返回后加一個while來判斷“條件”是否滿足要求。