C++并行开发8-condition_variable、wait、notify_one、notify_all
std::condition_variable
condition_variable实际上是一个类,说白了就是等待一个条件的达成
notify_one(); 尝试把wait的线程唤醒
wait() 用来等一个东西 如果第二个参数返回true,那么wait()直接返回,并继续执行 如果第二个参数返回false,那么wait()将解锁互斥量,并堵塞到本行一直堵塞到某一个线程调用notify_one为止; 如果wait()没有第二个参数,my_cond(sbguard1);那么就和第二个参数lambda直接返回false一样 wait()将解锁互斥量,并堵塞到本行,直到某一个线程调用notify_one成员函数为止
当其他线程用notify_one之后,wait就开始干活。干什么活呢? a) wait()不断的尝试重新获取互斥量锁,如果获取不到,那么流程就卡在wait这里等着获取,如果获取到了锁,那么流程就继续 b) 上锁(实际获取到了锁就相当于上锁 ) b.1) 如果表达式为false,那wait又对互斥量解锁,然后又休眠,等待再次被notify_one()唤醒 b.2) 如果lambda表达式为true,则wait返回,流程可以继续执行(此时互斥量已被锁住)。 b.3) 如果wait没有第二个参数,则wait返回,流程走下来
#include
#include
#include
#include
#include
#include
using namespace std;//调用类对象的成员函数的方式来创建线程
class A {
public:
void inMsgRecvQueue()
{
for (int i = 0; i < 10000; i++) {
cout << “inMsgRecvQueue执行,插入一个元素: “ << i << endl;
std::unique_lockstd::mutex sbguard1(my_mutex1); //尝试拿到锁头
msgRecvQueue.push_back(i);
my_cond.notify_one(); //尝试把wait的线程唤醒
// …执行其他代码
}
}
void outMsgRecgQueue() {
int commond = 0;
while (true) {
std::unique_lockstd::mutex sbguard1(my_mutex1);
//wait() 用来等一个东西
// 如果第二个参数返回true,那么wait()直接返回
// 如果第二个参数返回false,那么wait()将解锁互斥量,并堵塞到本行
// 一直堵塞到某一个线程调用notify_one为止;
// 如果wait()没有第二个参数,my_cond(sbguard1);那么就和第二个参数lambda直接返回false一样
// wait()将解锁互斥量,并堵塞到本行,直到某一个线程调用notify_one成员函数为止
// 当其他线程用notify_one之后,wait就开始干活。干什么活呢?
// a) wait()不断的尝试重新获取互斥量锁,如果获取不到,那么流程就卡在wait这里等着获取,如果获取到了锁,那么流程就继续
// b) 上锁(实际获取到了锁就相当于上锁 )
// b.1) 如果表达式为false,那wait又对互斥量解锁,然后又休眠,等待再次被notify_one()唤醒
// b.2) 如果lambda表达式为true,则wait返回,流程可以继续执行(此时互斥量已被锁住)。
// b.3) 如果wait没有第二个参数,则wait返回,流程走下来
my_cond.wait(sbguard1, [this] {
if (!msgRecvQueue.empty())
return true;
return false;
});
//流程走到这里,互斥锁一定是被锁着的, 同时是最少有一条数据的
commond = msgRecvQueue.front();
msgRecvQueue.pop_front();
sbguard1.unlock();
cout << “outMsgRecgQueue 执行, 取出一个元素” << commond << endl;
}
}
private:
listmsgRecvQueue; //消息队列
std::mutex my_mutex1;// 创建一个互斥量
std::condition_variable my_cond; //生成一个条件对象
};int main()
{
//条件变量condition_variable、wait、notify_one、notify_all
//线程A,等待一个条件满足
//线程B,专门向消息队列中扔数据
//std::condition_variable实际上是一个类,说白了就是等待一个条件的达成
//这个类需要和互斥量配合使用
A myobja;
std::thread myOutnMsgObj(&A::outMsgRecgQueue, &myobja);
std::thread myInnMsgObj(&A::inMsgRecvQueue, &myobja);
myOutnMsgObj.join();
myInnMsgObj.join();
return 0;
}
notify_one & notify_all
notify_one只是通知某一个正在wait的线程 notify_all是通知所有正在wait的线程
#include <iostream>
#include <thread>
#include <algorithm>
#include <vector>
#include <list>
#include <mutex>
using namespace std;
//调用类对象的成员函数的方式来创建线程
class A {
public:
void inMsgRecvQueue()
{
for (int i = 0; i < 10000; i++) {
cout << "inMsgRecvQueue执行,插入一个元素: " << i << endl;
std::unique_lock<std::mutex> sbguard1(my_mutex1); //尝试拿到锁头
msgRecvQueue.push_back(i);
//my_cond.notify_one(); //尝试把wait的线程唤醒
my_cond.notify_all(); //尝试把wait的线程唤醒
// ...执行其他代码
}
}
void outMsgRecgQueue() {
int commond = 0;
while (true) {
std::unique_lock<std::mutex> sbguard1(my_mutex1);
//wait() 用来等一个东西
// 如果第二个参数返回true,那么wait()直接返回
// 如果第二个参数返回false,那么wait()将解锁互斥量,并堵塞到本行
// 一直堵塞到某一个线程调用notify_one为止;
// 如果wait()没有第二个参数,my_cond(sbguard1);那么就和第二个参数lambda直接返回false一样
// wait()将解锁互斥量,并堵塞到本行,直到某一个线程调用notify_one成员函数为止
// 当其他线程用notify_one之后,wait就开始干活。干什么活呢?
// a) wait()不断的尝试重新获取互斥量锁,如果获取不到,那么流程就卡在wait这里等着获取,如果获取到了锁,那么流程就继续
// b) 上锁(实际获取到了锁就相当于上锁 )
// b.1) 如果表达式为false,那wait又对互斥量解锁,然后又休眠,等待再次被notify_one()唤醒
// b.2) 如果lambda表达式为true,则wait返回,流程可以继续执行(此时互斥量已被锁住)。
// b.3) 如果wait没有第二个参数,则wait返回,流程走下来
my_cond.wait(sbguard1, [this] {
if (!msgRecvQueue.empty())
return true;
return false;
});
//流程走到这里,互斥锁一定是被锁着的, 同时是最少有一条数据的
commond = msgRecvQueue.front();
msgRecvQueue.pop_front();
sbguard1.unlock();
cout << "outMsgRecgQueue 执行, 取出一个元素" << commond << endl;
}
}
private:
list<int> msgRecvQueue; //消息队列
std::mutex my_mutex1;// 创建一个互斥量
std::condition_variable my_cond; //生成一个条件对象
};
int main()
{
//条件变量condition_variable、wait、notify_one、notify_all
//线程A,等待一个条件满足
//线程B,专门向消息队列中扔数据
//std::condition_variable实际上是一个类,说白了就是等待一个条件的达成
//这个类需要和互斥量配合使用
//notify_all()
//
A myobja;
std::thread myOutnMsgObj1(&A::outMsgRecgQueue, &myobja);
std::thread myOutnMsgObj2(&A::outMsgRecgQueue, &myobja);
std::thread myInnMsgObj(&A::inMsgRecvQueue, &myobja);
myOutnMsgObj1.join();
myOutnMsgObj2.join();
myInnMsgObj.join();
return 0;
}
- Title: C++并行开发8-condition_variable、wait、notify_one、notify_all
- Author: FengLY
- Created at : 2023-06-18 22:40:09
- Updated at : 2023-06-18 22:57:49
- Link: https://zhouaq.com/2023/06/18/C++并行开发8-condition_variable、wait、notify_one、notify_all/
- License: This work is licensed under CC BY-NC-SA 4.0.