条件变量(Condition Variable)详解
条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法。举个简单的例子,应用程序A中包含两个线程t1和t2。t1需要在bool变量test_cond为true时才能继续执行,而test_cond的值是由t2来改变的,这种情况下,如何来写程序呢?可供选择的方案有两种:
- 第一种是t1定时的去轮询变量test_cond,如果test_cond为false,则继续休眠;如果test_cond为true,则开始执行。
- 第二种就是上面提到的条件变量,t1在test_cond为false时调用cond_wait进行等待,t2在改变test_cond的值后,调用cond_signal,唤醒在等待中的t1,告诉t1 test_cond的值变了,这样t1便可继续往下执行。
很明显,上面两种方案中,第二种方案是比较优的。在第一种方案中,在每次轮询时,如果t1休眠的时间比较短,会导致cpu浪费很厉害;如果t1休眠的时间比较长,又会导致应用逻辑处理不够及时,致使应用程序性能下降。第二种方案就是为了解决轮询的弊端而生的。然而条件变量在使用的过程中,比较容易出错,如何用得不正确的话,会适得其反的,接下来,我将详细分析如何来使用条件变量,希望能够给在使用条件变量过程中遇到问题的朋友有所帮助。
在开始介绍之前,需要说明一下,在接下来的介绍中,需要用到互斥锁和条件变量相关的内容,在这里我以Linux下的pthread_mutex_t为互斥锁类型,pthread_cond_t为条件变量类型来进行介绍,对pthread不熟的朋友,可以参考一下linux下的manual。
1. 下面是把刚开始举的例子翻译后的程序:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21pthread_mutex_t mutex; ///< 互斥锁
pthread_cond_t cond; ///< 条件变量
bool test_cond = false;
/// TODO 初始化mutex和cond
/// thread 1:
pthread_mutex_lock(&mutex); ///< 1
while (!test_cond)
{
pthread_cond_wait(&cond, &mutex); ///< 2,3
}
pthread_mutex_unlock(&mutex); ///< 4
RunThread1Func();
/// thread 2:
pthread_mutex_lock(&mutex); ///< 5
test_cond = true;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex); ///< 6
/// TODO 销毁mutex和cond通过上面的例子,下面我来介绍一下条件变量在使用过程中需要注意的几点(也是比较容易出错的):
(1)条件变量的使用过程中,最为关键的一点是互斥锁的使用。细心的朋友应该发现了,我在上面的例子中标了1、2、3、4、5、6个标号。在这里1、4、5、6都是正常的lock/unlock,2、3是需要特别说明的。2是进入pthread_cond_wait后的,pthread_cond_wait调的pthread_mutex_unlock,这样做的目的是为了保证在thread1阻塞wait后,thread2获取同一把锁mutex的时候,能够正常获取(即5,6)。3是thread1被唤醒后,要退出pthead_cond_wait之前,pthread_cond_wait调的pthread_mutex_lock,这样做的目的是为了把mutex的控制权还给调用pthread_cond_wait的线程(即thread1)。整理一下基本的时序为:1
2
3thread 1 lock->thread 1 wait-> thread 1 unlock(in wait)
->thread 2 lock->thread 2 signal->thread 2 unlock
->thread 1 lock(in wait)->thread 1 unlock(2)条件变量使用的过程中,通常会加一个bool或者int的值test_cond来配合使用。这里需要注意的一点是一定要在signal之前来改变test_cond,这样才能保证wait的线程被唤醒后,能够取到正确的test_cond的值,否则后果是不可预测的。
条件变量(Condition Variable)详解的更多相关文章
- [转] 条件变量(Condition Variable)详解
http://www.wuzesheng.com/?p=1668 条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法.举个简单的例子,应用程序A ...
- Python中的变量和作用域详解
Python中的变量和作用域详解 python中的作用域分4种情况: L:local,局部作用域,即函数中定义的变量: E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部 ...
- Node.js中环境变量process.env详解
Node.js中环境变量process.env详解process | Node.js API 文档http://nodejs.cn/api/process.html官方解释:process 对象是一个 ...
- 深入MySQL用户自定义变量:使用详解及其使用场景案例
一.前言 在前段工作中,曾几次收到超级话题积分漏记的用户反馈.通过源码的阅读分析后,发现问题出在高并发分布式场景下的计数器上.计数器的值会影响用户当前行为所获得积分的大小.比如,当用户在某超级话题下连 ...
- python线程条件变量Condition(31)
对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – 线程条件变量Condition. 一.线程条件变 ...
- Python变量和字符串详解
Python变量和字符串详解 几个月前,我开始学习个人形象管理,从发型.妆容.服饰到仪表仪态,都开始做全新改造,在塑造个人风格时,最基础的是先了解自己属于哪种风格,然后找到参考对象去模仿,可以是自己欣 ...
- JAVA JDK 环境变量配置 入门详解 - 精简归纳
JAVA JDK 环境变量配置 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 9 / 13 转载请注明出处!️ 目录 JAVA JDK 环境变量配置 入门详解 - 精简归纳 一.为什么j ...
- Python安装与环境变量配置 入门详解 - 精简归纳
Python安装与环境变量配置 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 9 / 24 转载请注明出处!️ 目录 Python安装与环境变量配置 入门详解 - 精简归纳 一.下载Py ...
- GoSDK的安装及环境变量配置 入门详解 - 精简归纳
GoSDK的安装及环境变量配置 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 10 / 29 转载请注明出处!️ 目录 GoSDK的安装及环境变量配置 入门详解 - 精简归纳 一.进入G ...
随机推荐
- 使用泛型类简化ibatis系统架构
jdk1.5的推出为我们带来了枚举.泛型.foreach循环.同步工具包等等好东西.其中,泛型的使用为我们的代码开发提供了很大的简便,简化了我们的代码. 1.设计思路 1)GenericDao泛型类提 ...
- Mac下安装Angular报错处理
安装 Angular CLI 命令: sudo npm install -g @angular/cli 打印如下错误:(权限问题) gyp WARN EACCES user "root&qu ...
- React-router4简约教程
React-router4简约教程 教程 webEmmet 17年10月 React-router和React-router-dom的选择 很多刚使用react的同学在接触到react ...
- css一些事儿
1. margin和padding 如果边界画一条线,则margin的属于边界外,padding属于边界内 当我们给元素背景色时,margin区域不会被着色,而padding区域会被着色. 当上下两个 ...
- 基于Python的selenuim自动化测试尝试
工作这么多年了,终于狠下心好好开始学学自动化测试相关知识,揭开这层神秘的面纱. 困难重重,障碍很多,但好在每天都多少有点小收获. 很感谢一个QQ好友推荐的虫师,也非常感谢在这个契机读到了虫师编著的&l ...
- appium-手势密码实现-automationName 是automator2
上一篇博客已经说了 appium-手势密码实现-automationName 是Appium的情况 下面就说一下automator2的情况: 手势密码的moveTo方法的参数进行了改变. 参数是相对于 ...
- selenium获取浏览器控制台日志
public void logsTest(){ WebDriver driver = null; try { System.setProperty("webdriver.chrome.dri ...
- 测试基础面试题 + SQL 面试题(选择题有部分答案,难度:低)
测试基础面试题 + SQL 面试题(选择题有部分答案,难度:低) 答案: .A .C .C .A .A .D
- 1.0 python-client以及ui自动化介绍
appium的client-----捕获元素和对元素进行操作都是在client里面去写脚本实现的,client会将你写的python脚本发送到appium server上,然后appium serv ...
- HA集群基本概念详解
一.高可用集群的定义 二.高可用集群的衡量标准 三.高可用集群的层次结构 四.高可用集群的分类 五.高可用集群常用软件 六.共享存储 七.集群文件系统与集群LVM 八.高可用集群的工作原理 一.高可用 ...