目录
1、condition_variable
等待中,增加了时延和开销,用条件变量就很快及时处理
1.1、生产者消费者模型
生产者和消费者共享资源变量(list队列);
生产者生产一个产品,通知消费者消费;
消费者阻塞等待信号,获取信号后消费产品(取出list队列中数据)
1.2、改变共享变量的线程步骤
准备好信号量
std::condition_variable cv;
1、获取std::mutex(常用std::unique_lock)
unique_lock lock(mux);
2、在获取锁时进行修改;
msgs_.push_back(data);
3、释放锁并通知读取线程
lock.unlock();
cv.notify_one();//通知一个等待信号线程
cv.notify_all;//通知所有等待信号线程
1.3、等待信号读取共享变量的线程步骤
1.3.1、获得改变共享变量线程共同的mutex
unique_lock lock(mux);
1.3.2、wait()等待信号通知
1.3.2.1、无lambda表达式
//解锁lock,并阻塞等待notify_one notify_all 通知
cv.wait(lock);
//接收到通知会再次获取锁标注,也就是说如果此时mux资源被占用,wait函数会阻塞
msgs_front();
//处理数据
msgs_pop_front();
1.3.2.2 lambda表达式
cv.wait(lock,[]{return !msgs_empty();})
只在std::unique_lockstd::mutex上工作的std::condition_variable
样例代码
#include <thread>
#include <iostream>
#include <mutex>
#include <list>
#include <string>
#include <sstream>
using namespace std;
list<string> msgs_;
mutex mux;
condition_variable cv;//条件变量
void ThreadWrite()
{
for (int i = 0;;i++)
{
stringstream ss;
ss << "Write msg " << i;
unique_lock<mutex> lock(mux);
msgs_.push_back(ss.str());
lock.unlock();//解锁
cv.notify_one();//通知一个
this_thread::sleep_for(1ms);
}
}
void ThreadRead(int i)
{
for (;;)
{
cout << "Read msg" << endl;
unique_lock<mutex> lock(mux);
cv.wait(lock);//解锁、阻塞等待信号
mambda表达式方式
//cv.wait(lock, [i]
//{
// cout << i << " wait" << endl;//特别这句话在啥时候会进入,调用多少次,搞不清楚就用上面cv.wait更简单
// //return true;//只要返回true,wait就不会阻塞
// return !msgs_.empty();
//
// });
//获取信号后锁定
while (!msgs_.empty())
{
cout << i << "read " << msgs_.front() << endl;
msgs_.pop_front();
}
if (msgs_.empty()) return;
}
}
int main()
{
thread th(ThreadWrite);
th.detach();
for (int i = 0; i < 3; i++)
{//读取线程
thread th2(ThreadRead,i+1);
th2.detach();
}
getchar();
return 0;
}
期间出差了一个月,没有时间学习,今天开始又继续学习和做笔记了…
辉2023.9.8