案例情景:
A线程:等待一个条件满足
B线程:专门给消息队列中加入消息
引入一个新的知识点: condition_variable
condition_variable的功能:实际上是一个类,是一个和条件相关的类,说白了就是等待一个条件的达成, 这个类必须和互斥量(mutex )来配合工作,用的时候要生产这个类的对象。
1、 wait 是在等一个东西,是一个成员函数如果 第二个参数(【this 】{}lambdaba表达式) 里面的返回值是false ,那么wait() 将解锁互斥量,并堵塞到这里,如果返回的是true ,则直接返回
2、 那什么时候解锁呢? 阻塞到其他线程调用 notifty_one() 成员函数的时候为止,也还是说 wait 和notifty_one 是一对搭档
3、如果wait() 成员函数中没有第二个参数my_c_v.wait(mylock2),则表示的是第二个参数返回的就是false4、当其他线程用notfity_one()唤醒本(这个阻塞)wait() 将解锁互斥量,那这个边开始干活,然后wait() 不断尝试去重新获得这个锁,这个会卡到这里,就会执行b
b: b1:如果wait() 有第二个参数,就判断这lambda 表达式,如果返回的是false,就讲wait 解锁,又等待再次唤醒
b2:lambda 表达式,如果返回的是true,此时锁还上锁定状态,就会接着走下面的流程
#if 1 class A { public: // 吧收到的消息 入到一个队列当中 void inMsgRecvQueue() { for (size_t i = 0; i < 10000; i++) { cout << "inMsgRecvQueue() 执行,插入一个元素 " << i << endl; unique_lockmylock2(my_mutex) ; my_c_v.notify_one(); // 唤醒 msgRecvQueue.push_back(i); } } // 另外一个线程 void getMsgRecvQueue() { int cmd = 0; while (1) { unique_lockmylock2(my_mutex) ; // wait 是在等一个东西,是一个成员函数如果 【this 】{} 这个里面的返回值是false ,那么wait() 将解锁互斥量,并堵塞到这里,如果返回的是true ,则直接返回 // 那什么时候解锁呢? 阻塞到其他线程调用 notifty_one() 成员函数的时候为止,也还是说 wait 和notifty_one 是一对搭档 // 如果wait() 成员函数中没有第二个参数my_c_v.wait(mylock2),则表示的是第二个参数返回的就是false // 当其他线程用notfity_one()唤醒本(这个阻塞)wait() 将解锁互斥量,那这个边开始干活,然后wait() 不断尝试去重新获得这个锁,这个会卡到这里,就会执行b // b: b1:如果wait() 有第二个参数,就判断这lambda 表达式,如果返回的是false,就讲wait 解锁,又等待再次唤醒 // b2:lambda 表达式,如果返回的是true,此时锁还上锁定状态,就会接着走下面的流程 my_c_v.wait(mylock2, [this] { // this 表示的是这个条件变量 if (msgRecvQueue.empty() == false) return true; return false; }); cmd = msgRecvQueue.front(); msgRecvQueue.pop_front(); mylock2.unlock(); cout << "msgRecvQueue 取出一个cmd !"<< cmd< } } private: list<int> msgRecvQueue; mutex my_mutex; // 创建一个互斥量 condition_variable my_c_v; // 生产一个条件对象 }; int main() { A a; thread mythread(&A::getMsgRecvQueue, &a); // 第二对象是 & thread mythread2(&A::inMsgRecvQueue, &a); mythread.join(); mythread2.join(); cout << "Hello World!\n"; } #endif