c++11多线程记录6:条件变量(condition variables)
https://www.youtube.com/watch?v=13dFggo4t_I视频地址
实例1
考虑这样一个场景:存在一个全局队列deque,线程A向deque中推入数据(写),线程B从deque中取出数据(读).
deque这个资源对象就需要用mutex做访问控制,代码如下:
std::deque<int> q;
std::mutex mu;
void func1() {
int ct = 10;
while (ct > 0) {
std::unique_lock<std::mutex> lock(mu);
q.push_front(ct);
lock.unlock();
std::this_thread::sleep_for(chrono::seconds(1));
ct --;
}
}
void func2() {
int data = 0;
while (data != 1 ) {
std::unique_lock<std::mutex> lock(mu);
if (!q.empty()) {
data = q.back();
q.pop_back();
lock.unlock();
...
} else {
lock.unlock();
}
}
}
int main() {
std::thread t1(func1);
std::thread t2(func2);
t1.join();
t2.join();
return 0;
}
线程t1中,循环向队列中推入数据,每次睡眠1秒;做为“生产者”.
线程t2中,不断地从队列中读出数据(先判断是否有数据);做为“消费者”.
存在一个问题:线程t2中,会先判断deque是否为空;如果为空,会执行unlock,然后马上进入下一次循环,造成busy waiting(反复频繁地判断某一状态是否为true).
一种解决方法如下:
void func2() {
...
} else {
lock.unlock();
std::this_thread::sleep_for(chrono::seconds(1));
}
}
在发现队列为空时睡眠一段时间time,可以一定程度上解决问题。
但是变量time设置成什么数值并不好确定;设置的过小,可能会回到busy waiting;设置的过大,会导致不能及时的获取数据
Condition variable
用条件变量可以很好的处理这个问题,让消费者不用“盲目等待”
std::deque<int> q;
std::mutex mu;
std::condition_variable cond;
void func1() {
int ct = 10;
while (ct > 0) {
std::unique_lock<std::mutex> lock(mu);
q.push_front(ct);
lock.unlock();
cond.notify_one(); // wake up one waiting thread
// cond.notify_all(); // wake up all waiting threads
std::this_thread::sleep_for(chrono::seconds(1));
ct --;
}
}
void func2() {
int data = 0;
while (data != 1 ) {
std::unique_lock<std::mutex> lock(mu);
cond.wait(lock, [](){ return !q.empty(); });
data = q.back();
q.pop_back();
lock.unlock();
}
}
生产者线程中,数据被推入deque后执行notify_one(),就可以唤醒某一个线程;类似于银行柜台叫号.
消费者线程中,只需要cond.wait(lock,...),睡眠等待,直到被“叫号”;睡眠等待过程中不占用cpu时间.(被唤醒时,第二个参数如果返回false会继续睡眠,为true则会往下执行)
注意这里cond.wait(lock)进入睡眠之前会先释放对lock的占用;被唤醒时会先占用mutex.
小结
condition_variable粗略的说,可能类似一个“唤醒服务”.
c++11多线程记录6:条件变量(condition variables)的更多相关文章
- [development][C] 条件变量(condition variables)的应用场景是什么
产生这个问题的起因是这样的: [:] <tong> lilydjwg: 主线程要启动N个子线程, 一个局部变量作为把同样的参数传入每一个子线程. 子线程在开始的十行会处理完参数. ...
- 深入解析条件变量(condition variables)
深入解析条件变量 什么是条件变量(condition variables) 引用APUE中的一句话: Condition variables are another synchronization m ...
- python线程条件变量Condition(31)
对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – 线程条件变量Condition. 一.线程条件变 ...
- 多线程编程中条件变量和的spurious wakeup 虚假唤醒
1. 概述 条件变量(condition variable)是利用共享的变量进行线程之间同步的一种机制.典型的场景包括生产者-消费者模型,线程池实现等. 对条件变量的使用包括两个动作: 1) 线程等待 ...
- python多线程编程5: 条件变量同步-乾颐堂
互斥锁是最简单的线程同步机制,Python提供的Condition对象提供了对复杂线程同步问题的支持.Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还 ...
- 练习生产者与消费者-PYTHON多线程中的条件变量同步-Queue
以前练习过,但好久不用,手生,概念也生了, 重温一下.. URL: http://www.cnblogs.com/holbrook/tag/%E5%A4%9A%E7%BA%BF%E7%A8%8B/ ~ ...
- [转] 条件变量(Condition Variable)详解
http://www.wuzesheng.com/?p=1668 条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法.举个简单的例子,应用程序A ...
- linux C++ 多线程使用pthread_cond 条件变量
1. 背景 多线程中经常需要使用到锁(pthread_mutex_t)来完成多个线程之间的互斥操作. 但是互斥锁有一个明显到缺点: 只有两种状态,锁定和非锁定. 而条件变量则通过允许线程阻塞并等待另一 ...
- java多线程技术之条件变量
上一篇讲述了并发包下的Lock,Lock可以更好的解决线程同步问题,使之更面向对象,并且ReadWriteLock在处理同步时更强大,那么同样,线程间仅仅互斥是不够的,还需要通信,本篇的内容是基于上篇 ...
随机推荐
- 洛谷 P2577 [ZJOI2005]午餐 题解
每日一题 day56 打卡 Analysis 算法:贪心+dp 容易想到贪心:吃饭慢的先打饭节约时间, 所以先将人按吃饭时间从大到小排序. 然后就是dp了: 首先,应该想到f[i][j][k]:前i个 ...
- luogu_1155: 双栈排序
洛谷1155:双栈排序 题意描述: 给定一个长度为\(n\)的序列\((n\leq 1000)\),两个初始为空的栈,问是否能借助以下四种操作将序列排为升序. \(1:\)如果序列不为空,将第一个元素 ...
- RFM模型的变形LRFMC模型与K-means算法的有机结合
应用场景: 可以应用在不同行业的客户分类管理上,比如航空公司,传统的RFM模型不再适用,通过RFM模型的变形LRFMC模型实现客户价值分析:基于消费者数据的精细化营销 应用价值: LRFMC模型构建之 ...
- [转]Reids配置文件redis.conf中文详解
转自: Reids配置文件redis.conf中文详解 redis的各种配置都是在redis.conf文件中进行配置的. 有关其每项配置的中文详细解释如下: 对应的中文版解释redis.conf # ...
- ubuntu 安装任何版本的Firefox
https://ftp.mozilla.org/pub/firefox/releases/ 1.sudo gedit /usr/share/applications/firefox.desktop 2 ...
- The real universe
- 【题解】 洛谷 P2649 游戏预言
题目: P2649 游戏预言 题意: John和他的好朋基友们在van纸牌游戏.共有\(m\)个人.纸牌有\(n \times m\)张,从\(1--n \times m\)编号.每人有\(n\)张. ...
- 第03组 Beta冲刺(3/4)
队名:不等式方程组 组长博客 作业博客 团队项目进度 组员一:张逸杰(组长) 过去两天完成的任务: 文字/口头描述: 制定了初步的项目计划,并开始学习一些推荐.搜索类算法 GitHub签入纪录: 暂无 ...
- 配置Zuul代理下游的认证
配置Zuul代理下游的认证 您可以通过proxy.auth.*设置控制@EnableZuulProxy下游的授权行为.例: application.yml proxy: auth: routes: c ...
- KMS服务器激活
https://blog.csdn.net/weixin_42588262/article/details/81120403 http://kms.cangshui.net/ https://kms. ...