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"); }