-
std::condition_variable使用要包含头文件#include <condition_variable>
-
定义condition_variable对象:
std::condition_variable my_cond;
-
condition_variable成员函数wait():
my_cond.wait(my_lock,[this]{ if (!msgQueue.empty()) { return true; }else { cout<<"msgQueue is empty!"<<" Thread_ID: "<<std::this_thread::get_id()<<endl;; return false; } });
(1)wait():如果第二个参数lambda表达式返回值是true,那么wait直接返回;
(2)wait():如果第二个参数lambda表达式返回值是false,那么wait()将解锁互斥量,并阻塞到本行,一直堵到其他线程调用notify_one()为止
(3)如果wait()没有第二个参数,即my_cond.wait(my_lock),那么就跟第二个参数lambda表达式返回false效果一样,wait()将解锁互斥量,并阻塞到本行,阻塞到其他某个线程调用notify_one()为止
(4)当其他线程用notify_one(),将wait()唤醒后,wait()不断尝试重新获取互斥量,如果获取不到,那么流程就卡在wait这里等着,如果获取到了锁,- 1)如果wait()有第二个参数(lambda),就判断这个lambda表达式,如果lambda表达式为false,那么wait又被睡眠
- 2)如果lambda表达式为true,则wait返回,向下走流程
- 3)如果wait()没有第二个参数,并且被唤醒了,就相当于第二个参数返回true,流程往下走。
-
condition_variable成员函数notify_one()唤醒一个线程
-
notify_all()可以通知多个线程
#include <iostream>
#include <thread>
#include <vector>
#include <iterator>
#include <list>
#include <mutex>
#include <condition_variable>
using namespace std;
class A {
public:
void writeMsg()
{
cout << "Thread writeMsg() is beginnig!" << " Thread_ID= " << std::this_thread::get_id() << endl;
for (int i=0; i<1000; i++)
{
cout << "Write " << i << " to msgQueue" << endl;
std::unique_lock<std::mutex> my_lock(myMutex);
msgQueue.push_back(i);
//假如readMsg正在处理一个事物,需要一段时间,而不是正在卡在wait()那等你唤醒,那么此时这个notify_one可能不起作用。
//notify_one()只能通知一个线程
//notify_all()可以通知多个线程
my_cond.notify_one();//尝试唤醒wait(),那么readMsg()中的wait就会被唤醒
}
cout << "Thread writeMsg() is over!" << " Thread_ID= " << std::this_thread::get_id() << endl;
}
void readMsg()
{
cout << "Thread readMsg() is beginnig!" << " Thread_ID= " << std::this_thread::get_id() << endl;
for (int i = 0; i<1000; i++)
{
std::unique_lock<std::mutex> my_lock(myMutex);
//wait():如果第二个参数lambda表达式返回值是true,那么wait直接返回;
//wait():如果第二个参数lambda表达式返回值是false,那么wait()将解锁互斥量,并阻塞到本行,一直堵到其他线程调用notify_one()为止;
//如果wait()没有第二个参数,即my_cond.wait(my_lock),那么就跟第二个参数lambda表达式返回false效果一样,wait()将解锁互斥量,并阻塞到本行,阻塞到其他某个线程调用notify_one()为止
//当其他线程用notify_one(),将wait()唤醒后,wait()不断尝试重新获取互斥量,如果获取不到,那么流程就卡在wait这里等着,如果获取到了锁,
//如果wait()有第二个参数(lambda),就判断这个lambda表达式,如果lambda表达式为false,那么wait又被睡眠
//如果lambda表达式为true,则wait返回,向下走流程
//如果wait()没有第二个参数,并且被唤醒了,就相当于第二个参数返回true,流程往下走。
my_cond.wait(my_lock,[this]{
if (!msgQueue.empty())
{
return true;
}else {
cout<<"msgQueue is empty!"<<" Thread_ID: "<<std::this_thread::get_id()<<endl;;
return false;
}
});
//如果流程能走到这,一定是锁着的状态。
int cmd=msgQueue.front();
cout<<"Read "<<cmd<<" from msgQueue!"<<" Thread_ID: "<<std::this_thread::get_id()<<endl;
msgQueue.pop_front();
my_lock.unlock();
}
cout << "Thread readMsg() is over!" << " Thread_ID= " << std::this_thread::get_id() << endl;
}
private:
list<int> msgQueue;
mutex myMutex;
mutex myMutex1;
mutex myMutex2;
std::condition_variable my_cond;
};
void example()
{
A myobj;
thread writeThread(&A::writeMsg, &myobj);
thread readThread(&A::readMsg, &myobj);
thread readThread1(&A::readMsg, &myobj);
writeThread.join();
readThread.join();
readThread1.join();
}
int main(int argc, char *argv[])
{
cout << "Main thread is begining!" << endl;
example();
cout << "Main thread is over!" << endl;
return 0;
}