pthread_cond_wait的理解

使用流程

等待線程:

pthread_mutex_lock(&mutex);

if(條件不滿足)

  pthread_cond_wait(&cond, &mutex);

//處理共享資源

pthread_mutex_unlock(&mutex);

 

激活線程:

pthread_mutex_lock(&mutex);

pthread_cond_signal(&cond);

pthread_mutex_unlock(&mutex);

 

下面寫了一個例子

複製代碼

複製代碼

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <iostream>
using namespace std;

int count = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 
//該函數增加count數值
void * creator(void * arg)
{
    cout << "creator add lock" << endl;
    pthread_mutex_lock(&mutex);

    count ++;

    cout << "in creator count is : " << count << endl;
    //條件滿足時發送信號
    if(count > 0)
    {

        pthread_cond_signal(&cond);
    }

    
    cout << "creator release lock" << endl;
    
    pthread_mutex_unlock(&mutex);

    return NULL;

}

//該函數減少count數值
void * consumer(void * arg)
{
    cout << "consumer add lock" << endl;

    pthread_mutex_lock(&mutex);
    //當條件不滿足時等待
    if(count <= 0)
    {
        cout << "begin wait" << endl;
        pthread_cond_wait(&cond,&mutex);
        cout << "end wait" << endl;
    }

    count --;

    cout << "in consumer count is " << count << endl;

    pthread_mutex_unlock(&mutex);

    cout << "consumer release lock" << endl;
    
    return NULL;
    
}


int main()
{
    //兩個線程,一個生產者線程一個消費者線程
    pthread_t createthread,consumethread;

     pthread_create(&consumethread, NULL, consumer, NULL);
   sleep(2);
    pthread_create(&createthread, NULL, creator, NULL);
    
    //主進程等待兩個線程結束
    pthread_join(createthread, NULL);
    pthread_join(consumethread, NULL);
    return 0;
}

複製代碼

複製代碼

因爲消費者線程先跑起來,會等待生產者增加count數量,所以打印輸出結果如下

下面將消費者和生產者線程增加幾個,creater和consumer內部用循環處理,

這樣就能看出效果了。

 

複製代碼

複製代碼

void * creator(void * arg)
{
    int i = 0;
    while(i<300)
    {

        i++;
        cout << "creator add lock" << endl;
        pthread_mutex_lock(&mutex);

        count ++;

        cout << "in creator count is : " << count << endl;

        if(count > 0)
        {

            pthread_cond_signal(&cond);
        }

    
        cout << "creator release lock" << endl;
    
        pthread_mutex_unlock(&mutex);

    }

    return NULL;

}





void * consumer(void * arg)
{
    int i = 0;
    while(i < 100)
    {
        
        i++;
        cout << "consumer add lock" << endl;

        pthread_mutex_lock(&mutex);

        if(count <= 0)
        {
            cout << "begin wait" << endl;
            pthread_cond_wait(&cond,&mutex);
            cout << "end wait" << endl;
        }

        count --;

        cout << "in consumer count is " << count << endl;

        pthread_mutex_unlock(&mutex);

        cout << "consumer release lock" << endl;
    }
    
    return NULL;
    
}


int main()
{
     pthread_t createthread[2],consumethread[3];

     for(int i = 0; i < 3; i++)
     {
        pthread_create(&consumethread[i], NULL, consumer, NULL);
     }
     
     for(int i = 0; i < 2; i++)
     {
        pthread_create(&createthread[i], NULL, creator, NULL);
         }
     
     for(int i = 0; i < 2; i++)
      {
        pthread_join(createthread[i], NULL);
         }

     for(int i = 0; i < 3; i++)
     {
         pthread_join(consumethread[i], NULL);
     }

    
    return 0;

}

==============================================================================================================

接下來講解使用while和if判斷線程執行條件是否成立的區別。一般來說,在多線程資源競爭的時候,在一個使用資源的線程裏面(消費者)判斷資源是否可用,不可用便調用pthread_cond_wait,在另一個線程裏面(生產者)如果判斷資源可用的話,則調用pthread_cond_signal發送一個資源可用信號。但是在wait成功之後,資源就一定可以被使用麼,答案是否定的,如果同時有兩個或者兩個以上的線程正在等待此資源,wait返回後,資源可能已經被使用了,在這種情況下,應該使用:

while(resource == FALSE)

      pthread_cond_wait(&cond, &mutex);

如果之後一個消費者,那麼使用if就可以了。解釋一下原因,分解pthread_cond_wait的動作爲以下幾步:

1,線程放在等待隊列上,解鎖

2,等待 pthread_cond_signal或者pthread_cond_broadcast信號之後去競爭鎖

3,若競爭到互斥索則加鎖。

上面講到,有可能多個線程在等待這個資源可用的信號,信號發出後只有一個資源可用,但是有A,B兩個線程都在等待,B比較速度快,獲得互斥鎖,然後加鎖,消耗資源,然後解鎖,之後A獲得互斥鎖,但他回去發現資源已經被使用了,它便有兩個選擇,一個是去訪問不存在的資源,另一個就是繼續等待,那麼繼續等待下去的條件就是使用while,要不然使用if的話pthread_cond_wait返回後,就會順序執行下去。

    下面來講一下:pthread_cond_wait和pthread_cond_singal是怎樣配對使用的:

     等待線程:

     pthread_cond_wait前要先加鎖
     pthread_cond_wait內部會解鎖,然後等待條件變量被其它線程激活
     pthread_cond_wait被激活後會再自動加鎖
     激活線程:
     加鎖(和等待線程用同一個鎖)
     pthread_cond_signal發送信號(階躍信號前最好判斷有無等待線程)
     解鎖
     激活線程的上面三個操作在運行時間上都在等待線程的pthread_cond_wait函數內部。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章