1. 簡介
Condition 類是條件變量。它依賴于某個Mutex 互斥體,互斥體加鎖時阻塞所在的線程,解鎖或者超過時限則釋放此線程,允許其繼續運作。這裡涉及了幾個線程操作中重要的概念:同步,阻塞以及條件變量。線程同步,簡單來說就是使同一程序的多個線程可以協調工作,例如讓它們都在指定的執行點等待對方,直到全員到期之後才開始同步運作;擁塞,即強制一個線程在某個執行點上等待,直到滿足繼續運作的條件為止。例如其它的線程到達同一執行點,某個變量初始化完成等等,可以通過條件變量來設計各種條件。
條件變量有點類似于一種事件,用來通知兩個或者更多線程。可以讓一個或者多個線程等待條件變量的通知,另一個線程可以觸發這些通知。
關于條件變量的使用場景可以參考條件變量(Condition Variable)詳解
2. 使用方式
OSG裡面的條件變量提供的接口非常少,下面一一列舉:
-
wait(Mutex *mutex)
用來擷取一個Mutex,并且判斷目前條件是否滿足,如果條件不滿足,那麼進入到阻塞狀态,并且釋放這個Mutex
-
wait(Mutex *mutex, unsigned long int ms)
擷取一個Mutex,等待ms的時間
-
signal
其他線程的線程通過調用這個函數來喚醒阻塞的一個線程
-
broadcast
其他線程通過調用這個函數來喚醒所有被阻塞的線程
關于條件變量的使用方式,可以參考《用條件變量實作事件等待器的正确與錯誤做法》
3.示例程式
#include "header.h"
#include <OpenThreads/Thread>
#include <OpenThreads/Condition>
#include <OpenThreads/Mutex>
#include <OpenThreads/ScopedLock>
#include <iostream>
OpenThreads::Mutex g_mutex;
OpenThreads::Condition g_condition;
bool ready = false;
//WorkThread是被阻塞,等待喚醒的線程
class WorkThread : public OpenThreads::Thread
{
public:
WorkThread(){ }
void run()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> mutex(g_mutex);
while (!ready)
{
g_condition.wait(&g_mutex);
}
std::cout << "Work Thread Wake up and coming" << std::endl;
}
};
//NodifyThread是喚醒被阻塞線程的線程
class NotifyThread : public OpenThreads::Thread
{
public:
NotifyThread(){}
void run()
{
std::cout << "Start Notify Thread" << std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> mutex(g_mutex);
ready = true;
std::cout << "Work Thread Go!" << std::endl;
g_condition.signal();
}
};
int main()
{
WorkThread w;
NotifyThread n;
w.start();
n.start();
w.join();
n.join();
4. 參考資料
1. std::condition_variable
2. 條件變量(Condition Variable)詳解
3. 用條件變量實作事件等待器的正确與錯誤做法