Linux多線程開發-線程同步-條件變量

1、條件變量的概念

一個線程A的執行需要另一個線程B來喚醒,否則A掛起等待。線程B可以產生線程A繼續執行的信號。條件變量常用在共享數據狀態變化的場景中,例如:生產則和消費者問題。POSIX線程庫提供了條件變量這種同步機制。使用條件變量需要聯合互斥鎖一起使用。

2、如何聲明一個條件變量

#include <pthread.h>

pthread_cond_t cond;

3、如何初始化一個條件變量

//靜態初始化條件變量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
 
//動態初始化條件變量
pthread_cond_t cond;
pthread_cond_init(&cond,NULL);

//結合互斥鎖的條件變量初始化結構變量
typedef struct{
    pthread_mutex_t mutex;//互斥
    pthread_cond_t cond;//條件
    int  value;//變量資源
}mutexcond_t;

mutexcond_t mymutexcond = {PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER,0};

靜態初始化的條件變量不需要銷燬,動態初始化的條件變量需要銷燬,銷燬函數聲明如下:

int pthread_cond_destroy(pthread_cond_t *cond);

4、如何阻塞含條件變量的線程

線程執行等待條件變量後,將一直阻塞或計時阻塞,兩個函數接口:pthread_cond_wait,pthread_cond_timewait。

int pthread_cond_wait(pthread_cond_t * restrict cond, pthread_mutex_t *restrict mutex);

int pthread_cond_timewait(pthread_cond_t * restrict cond,
                           pthread_mutex_t *restrict mutex,
                           const struct timespec *restrict abstime);

關鍵字:restrict,限制,表明指針修飾的指針是訪問一個數據對象的惟一且初始的方式。

pthread_cond_wait傳入兩個參數,一個條件變量cond指針和一個互斥變量mutex指針。互斥變量的作用是防止多線程同時調用pthread_cond_wait形成競爭。

5、如何喚醒等待條件變量的線程

//只喚醒一個等待條件變量的線程
int pthread_cond_signal(pthread_cond_t *cond);

//喚醒所有等待條件變量的線程
int pthread_cond_broadcast(pthread_cond_t *cond);

6、總結用法

條件變量和互斥鎖的用法比較繞,總結一下就是。

  • 調用pthread_cond_wait之前,必須給互斥鎖上鎖pthread_mutex_lock(&mutex)。
  • 一旦執行到pthread_cond_wait,如果沒有收到pthead_cond_signal發出的cond信號,pthread_cond_wait會自動解鎖,並一直阻塞。
  • 一旦pthread_cond_wait收到pthread_cond_signal發出的cond信號,pthread_cond_wait會自動加鎖,因此,條件變量滿足後進入臨界區,執行結束需要pthread_mutex_unlock(&mutex)解鎖。
// 線程1 
{
    pthread_mutex_lock(&mutex);
    ...
        pthread_cond_signal(&cond);//喚醒等待cond的線程
    ...
    pthread_mutex_unlock(&mutex);
}

// 線程2
{
    pthread_mutex_lock(&mutex);
    ...
        pthread_cond_wait(&cond,&mutex);//等待條件變量
    ...
    pthread_mutex_unlock(&mutex);
}

 

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