条件变量(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 ...
随机推荐
- 27-Middleware管道介绍
1-Middleware管道介绍,. 如果匹配上/task,则界面只会显示i am task. public void Configure(IApplicationBuilder app, IHost ...
- python-12正则表达式
import re #re.search方法 re.search 扫描整个字符串并返回第一个成功的匹配. re.match('com', 'www.runoob.com') #匹配失败 None re ...
- python使用网易邮箱发邮件
# -*- coding: UTF-8 -*- import smtplib from email.mime.text import MIMEText import email.mime.multip ...
- linpack_2
Run linpack in server 1.Get computer nodal information lscpu dmidecode -t memory | head -45 | tail - ...
- 从Wireshark看TCP连接的建立与关闭
TCP是一种面向连接.可靠的协议.TCP连接的建立与断开,都是需要经过通信双方的协商.用一句话概括就是:三次握手say hello(建立连接):四次握手say goodbye(断开连接).要了解TCP ...
- 《Cracking the Coding Interview》——第7章:数学和概率论——题目4
2014-03-20 02:16 题目:只用加法和赋值,实现减法.乘法.除法. 解法:我只实现了整数范围内的.减法就是加上相反数.乘法就是连着加上很多个.除法就是减到不能减为止,数数总共减了多少个. ...
- CodeIgniter学习笔记四:CI中的URL相关函数,路由,伪静态,去掉index.php
一.URL相关函数 1.加载url模块 加载url有两种方式: a.自动加载:在 application/config/autoload.php 中开启 $autoload['helper'] = a ...
- 你的第一个自动化测试:Appium 自动化测试
前言: 这是让你掌握 App 自动化的文章 一.前期准备 本文版权归作者和博客园共有,原创作者:http://www.cnblogs.com/BenLam,未经作者同意必须在文章页面给出原文连接. 1 ...
- Docker私有仓库Harbor部署与使用
一.harbor介绍 Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器. 由下面几个组件组成: proxy:nginx前端代理,主要是分发前端页面ui访问和镜像上传和下载 ...
- ASP.NET Core 2.1 源码学习之 Options[3]:IOptionsMonitor 【转】
原文链接:https://www.cnblogs.com/RainingNight/p/strongly-typed-options-ioptions-monitor-in-asp-net-core. ...