生产者消费者模式及条件变量
1、基础概念:
1.1、什么是生产者-消费者模式?
比如有两个线程A和B,它们共享一个固定大小的数组,A线程产生数据放入数组,B线程从数组中取出数据进行计算,那么这里其实就是一个生产者和消费者的模式,A相当于生产者,B相当于消费者。
1.2、为什么要使用生产者消费者模式?
在多线程开发中,如果生产者生产数据的速度很快,而消费者消费数据的速度很慢,那么生产者就必须等待消费者消费完了数据才能够继续生产数据,因为生产那么多也没有地方放啊;同理如果消费者的速度大于生产者那么消费者就会经常处理等待状态,所以为了达到生产者和消费者生产数据和消费数据之间的平衡,那么就需要一个缓冲区用来存储生产者生产的数据,所以就引入了生产者-消费者模式。
2、必备语法知识:关于线程阻塞、唤醒相关的函数
2.1、条件变量 std::condition_variable_any(Condition variable (any lock)) 与std::condition_variable
解释:两个条件变量作用相同,差别只在std::condition_variable的wait函数只能接受unique_lock<mutex>做参数,而std::condition_variable_any可接受任意锁对象类型作为参数。
2.2、condition_variable_any::wait
作用: 阻塞当前线程,直到该条件变量被唤醒
解释: 当前加锁的线程,在调用wait函数后,阻塞当前线程,同时自动调用lck.unlock()释放锁(供其他线程获取锁),直到被唤醒。
详细解释: http://www.cplusplus.com/reference/condition_variable/condition_variable_any/wait/
2.3、condition_variable_any::wait_for
作用: 与函数wait一致,但有超时时间,超时后自动唤醒
2.4、condition_variable_any::notify_all
作用: 唤醒当前等待该条件变量的所有线程
2.5、condition_variable_any::notify_one
作用: 唤醒一个等待该条件变量的线程
具体使用方式见生产者消费者用例:
生产者消费者官方案例:
// condition_variable::notify_one
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variablestd::mutex mtx;
std::condition_variable produce,consume;int cargo = 0; // shared value by producers and consumersvoid consumer () {std::unique_lock<std::mutex> lck(mtx);while (cargo==0) consume.wait(lck);std::cout << cargo << '\n';cargo=0;produce.notify_one();
}void producer (int id) {std::unique_lock<std::mutex> lck(mtx);while (cargo!=0) produce.wait(lck);cargo = id;consume.notify_one();
}int main ()
{std::thread consumers[10],producers[10];// spawn 10 consumers and 10 producers:for (int i=0; i<10; ++i) {consumers[i] = std::thread(consumer);producers[i] = std::thread(producer,i+1);}// join them back:for (int i=0; i<10; ++i) {producers[i].join();consumers[i].join();}return 0;
}
3、生产者消费者加解锁、阻塞唤醒机制
- 容器中数据状态的一致性:为了防止多个生产、消费者同时访问容器中数据,因此对于该容器的任何访问都需要加锁。
- 生产者加锁,put数据后,需要释放锁,同时唤醒消费者线程,若容器已满,则同时阻塞自己(当前生产线程)。
- 消费者加锁,take数据后,需要释放锁,同时唤醒生产者线程,若容器为空,则同时阻塞自己(当前消费线程)。
3.1、生产者消费者代码用例:
- http://www.cplusplus.com/reference/condition_variable/condition_variable/notify_one/
- https://zhuanlan.zhihu.com/p/83812690
4、总结:
1、条件变量让线程阻塞时回自动释放锁。
2、阻塞线程被唤醒时自动获取锁。
参考资料:
1、基础概念及图文理解参考
2、函数语法
生产者消费者模式及条件变量相关推荐
- C++多线程快速入门(三):生产者消费者模型与条件变量使用
互斥锁完成 #include <iostream> #include <deque> #include <thread> #include <mutex> ...
- 2022-2-3 牛客C++项目 —— 生产者消费者模型(条件变量、信号量)
如果生产者将容器填满,需要通知消费者, 如果消费者将容器清空,需要通知生产者. (我个人觉得如果有多个生产者和消费者,就排成队列,通知第一个就行.不知道实际情况是什么样子的) /* 生产者消费者模型( ...
- linux 生产者消费者 多进程,Linux多线程,生产者消费者算法和条件变量的使用
接着上一篇博文,原来双线程,现在为了实现 暂停/继续 功能,又加了一个线程.第三线程使用条件信号量,当用户按下S键,第三线程将检测到,并且将ifpause置为1,然后输出线程将在if语句成立后被条件信 ...
- 生产者消费者模型(条件变量)
三种关系:互斥,同步,互斥和同步 两类角色:生产者,消费者(线程) 一个交易场所:生产者消费者共享的区域 卖苹果的模型 dish上面只有一个苹果 买家必须要等卖家把苹果放到dish上才可以去买苹果. ...
- 3.12-3.14生产者和消费者模型、条件变量、信号量
目录 1.生产者消费者模型 2.条件变量 3.信号量 1.生产者消费者模型 2.条件变量 3.信号量 初始化的值:生产者-目前可以生产几个 -n 消费者-目前可以消费几个 -0
- java lock condition_Java 通过 Lock 和 竞争条件 Condition 实现生产者消费者模式
更多 Java 并发编程方面的文章,请参见文集<Java 并发编程> 竞争条件 多个线程共享对某些变量的访问,其最后结果取决于哪个线程偶然在竞争中获胜. condition.await() ...
- 【C++】多线程(链式、循环队列)实现生产者消费者模式
生产者消费者模式: 生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同 ...
- 生产者/消费者模式(阻塞队列)
生产消费者模式 貌似也是阻塞的问题 花了一些时间终于弄明白这个鸟东东,以前还以为是不复杂的一个东西的,以前一直以为和观察者模式差不多(其实也是差不多的,呵呵),生产消费者模式应该是可以通过观察者模 ...
- Qt之线程同步(生产者消费者模式 - QWaitCondition)
简述 生产者将数据写入缓冲区,直到它到达缓冲区的末尾,这时,它从开始位置重新启动,覆盖现有数据.消费者线程读取数据并将其写入标准错误. Wait condition(等待条件)比单独使用 mut ...
最新文章
- nltk自然语言处理
- T-SQL 之 表变量和临时表
- Java Review - 并发编程_ThreadPoolExecutor原理源码剖析
- 力士乐伺服电机编码器调零_力士乐伺服电机编码器故障维修来这里
- 为什么需要MapReduce?
- Java 包及访问权限
- WSAAsyncSelect() 非阻塞模式WinSock
- 如果把钱存入余额宝时,所有人都在受益,那么谁在亏损呢?
- 迁移是10g-11g ogg正好有用武之地N种方法
- 通俗易懂的Monte Carlo积分方法(二)
- Android启动的init进程
- 揭榜|2021年度“博客之星新星”十佳博主出炉
- html左斜杠转义字符,html的右斜杠转义符号是什么呢
- charles介绍及代理设置
- 懒人的法宝——办公自动化!
- 【老九学堂】【初识C语言】编码规范
- python基础语法和变量
- 用这个C语言骰子代码做选择
- java 图片格式转化 wmf,emf -> svg,png
- c刊计算机领域见刊快的期刊,见刊快的核心期刊_见刊快的核心期刊_好投的医学核心期刊...
热门文章
- mysql存储过程语法错误1064_mysql,dos下执行SQL语句创建存储过程出错ERROR 1064 (42000):...
- 开烧 Dvorak(德沃夏克)键盘
- Windows Phone 7编程实践—必应地图导航
- 【每日一题】打卡 13
- Chrome浏览器添加自定义搜索引擎-快速进行站内搜索
- inStream parameter is null
- ACP 学习-06-对象存储 OSS
- Eclipse下打jar、ear包
- DSPE-NH2 二硬脂酰基磷脂酰乙醇胺-氨基 DSPE-PEG5K-NH2
- 软件测试基础-(如何设计一个好的测试用例)