1.作用:在C++11中,我們可以使用條件變量(std::condition_variable)實現多個線程間的同步操作;當條件不滿足時,相關線程被一直阻塞,並釋放CPU,直到某種條件出現,這些線程才會被喚醒。條件變量需要和互斥量(鎖)一起搭配使用。
用在多線程中。
線程A:等待一個條件滿足
線程B:專門在消息隊列中扔消息,線程B觸發了這個條件,A就滿足條件了,可以繼續執行
2.常用的成員函數:
(1)wait():阻塞當前線程,直到條件變量被喚醒。
(2)wait_for:阻塞當前線程,直到條件變量被喚醒或到達指定時長后。
(3)wait_until:阻塞當前線程,直到條件變量被喚醒,或知道抵達指定的時間點。
(4)notify_once:通知一個等待的線程。
(5)notify_all:通知所有等待的線程。
3.范例代碼

#include <iostream> #include<thread> #include<string> #include<vector> #include<algorithm> #include<windows.h> #include<list> #include<mutex> using namespace std; class myClass { public: void AddOrder() { for (int i = 0; i < 10000; i++) { cout << "addOrder執行,插入一個元素" << i << endl; std::unique_lock<std::mutex> sbGuard(m_mutex); m_orderList.push_back(i); //我們嘗試把wait()的線程喚醒, //注意:如果其他線程在wait時,調用notify_one,可以喚醒,但是當其他線程沒有在wait時,執行的notify_one沒有用 m_Cond.notify_one(); } } void RemoveOrder() { int command; while (true) { std::unique_lock<std::mutex> sbGuard(m_mutex); //如果第二個參數lambda表達式返回值是true,那么wait()直接返回; //如果第二個闡述lambda表達式返回值是false,那么wait()將解鎖互斥量,並阻塞到本行, //那么阻塞到什么時候為止呢,阻塞到其他某個線程調用notify_once()成員函數為止; //如果wait()沒有第二個參數:m_Cond.wait(sbGuard),那么就跟第二個參數lambda表達式返回false效果一樣, //當其他線程用notify_once()將本wait(原來是阻塞狀態)喚醒,wait就開始回復工作,wait不斷的嘗試重新獲取互斥量鎖 // (a)如果拿不到鎖,它會不斷嘗試取獲取 // (b)如果獲取到鎖后: // (b.1):拿到鎖,如果wait有第二個參數,就判斷這個lambda表達式,如果lambda表達式為false,那么wait又對互斥量鎖解鎖又開始阻塞 // (b.2):如果lambda表達式為true,則wait返回,流程往下走 // (b.3):如果wait沒有第二個參數,則wait返回,流程往下走 m_Cond.wait(sbGuard, [this] { //一個lambda就是一個可調用對象(函數) if (!m_orderList.empty()) return true; return false; }); command = m_orderList.front(); // 返回m_orderList第一個元素 m_orderList.pop_front(); //移除m_orderList第一個元素 sbGuard.unlock(); //unique_lock靈活,可以隨時解鎖,以免鎖住太長時間 cout << "RemoveOrder取出一個元素" << command << endl; //其他任務 } } private: std::list<int> m_orderList; std::mutex m_mutex; std::condition_variable m_Cond; //生成一個條件變量對象 }; int main() { myClass my; std::thread obj1(&myClass::AddOrder, &my); std::thread obj2(&myClass::RemoveOrder, &my); obj1.join(); obj2.join(); system("pause"); }