pthread_cond_signal驚群現象


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來判斷“條件”是否滿足要求。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM