http://www.wuzesheng.com/?p=1668

条件变量(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
21
pthread_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
3
thread 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)详解的更多相关文章

  1. 条件变量(Condition Variable)详解

    条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法.举个简单的例子,应用程序A中包含两个线程t1和t2.t1需要在bool变量test_cond ...

  2. Python中的变量和作用域详解

    Python中的变量和作用域详解 python中的作用域分4种情况: L:local,局部作用域,即函数中定义的变量: E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部 ...

  3. Node.js中环境变量process.env详解

    Node.js中环境变量process.env详解process | Node.js API 文档http://nodejs.cn/api/process.html官方解释:process 对象是一个 ...

  4. 深入MySQL用户自定义变量:使用详解及其使用场景案例

    一.前言 在前段工作中,曾几次收到超级话题积分漏记的用户反馈.通过源码的阅读分析后,发现问题出在高并发分布式场景下的计数器上.计数器的值会影响用户当前行为所获得积分的大小.比如,当用户在某超级话题下连 ...

  5. python线程条件变量Condition(31)

    对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – 线程条件变量Condition. 一.线程条件变 ...

  6. Python变量和字符串详解

    Python变量和字符串详解 几个月前,我开始学习个人形象管理,从发型.妆容.服饰到仪表仪态,都开始做全新改造,在塑造个人风格时,最基础的是先了解自己属于哪种风格,然后找到参考对象去模仿,可以是自己欣 ...

  7. JAVA JDK 环境变量配置 入门详解 - 精简归纳

    JAVA JDK 环境变量配置 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 9 / 13 转载请注明出处!️ 目录 JAVA JDK 环境变量配置 入门详解 - 精简归纳 一.为什么j ...

  8. Python安装与环境变量配置 入门详解 - 精简归纳

    Python安装与环境变量配置 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 9 / 24 转载请注明出处!️ 目录 Python安装与环境变量配置 入门详解 - 精简归纳 一.下载Py ...

  9. GoSDK的安装及环境变量配置 入门详解 - 精简归纳

    GoSDK的安装及环境变量配置 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 10 / 29 转载请注明出处!️ 目录 GoSDK的安装及环境变量配置 入门详解 - 精简归纳 一.进入G ...

随机推荐

  1. call 方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法.

    call 方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法. 注意:该函数的语法与 apply() 方法的语法几乎完全相同,唯一的区别在于,apply()方法接受的是一个参 ...

  2. 如何去掉textarea右下角的灰色角标?

    在css中定义: resize: none; ,这个样式同时禁用textarea调整大小

  3. JS 导出图片,toDataURL

    //输出图片 function exportCanvasAsPNG(id, fileName) { //获取canvas元素 var canvasElement = document.getEleme ...

  4. Grnymotion模拟器和Android真机访问PC端Tomcat下的应用

    最近因为要学安卓与服务器交互的知识,所以必须要让android程序能访问一个测试服务器.所以我就考虑让真机或者模拟器访问PC端的Tomcat或者Apache服务. 在介绍步骤之前,有必要说点基础的.我 ...

  5. 项目管理模式——Projects

    Github 新的项目管理模式——Projects Github 新的项目管理模式——Projects Issues Github 中传统的项目管理是使用 issue 和 pull request 进 ...

  6. ios新特征 ARC详解

    IOS ARC 分类: IOS ARC2013-01-17 09:16 2069人阅读 评论(0) 收藏 举报   目录(?)[+]   关闭工程的ARC(Automatic Reference Co ...

  7. HashMap通过value反查key

            这是今天做了一道字符串的问题,一直MLE,所以想到了减少Map里对应关系数量来降低内存开销.随手谷歌,整理出了如下资料.       如果效率优先的话还是写俩Map吧. import ...

  8. 揪出“凶手”——实战WinDbg分析电脑蓝屏原因

    http://www.appinn.com/blue-screen-search-code/ 蓝屏代码查询器 – 找出蓝屏的元凶 11 文章标签: windows / 系统 / 蓝屏. 蓝屏代码查询器 ...

  9. InstallShield limited edition 生成单个 setup.exe 安装文件

    1.vs里选中当前Setup项目, 2.在vs工具栏中"配置管理器"的下拉列表里,把"Debug"改为"SingleImage" 3.重新编 ...

  10. UVA 10706 Number Sequence (找规律 + 打表 + 查找)

    Problem B Number Sequence Input: standard input Output: standard output Time Limit: 1 second A singl ...