关于condition variable的理解
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近在学习多线程的时候遇到了一个问题,那就是在使用conditions进行同步时,需要加锁。文档中给出的代码如下。</span>
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-124690
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">这是第一个线程的,</span>
pthread_mutex_t mutex;
pthread_cond_t condition;
Boolean ready_to_go = true; void MyCondInitFunction()
{
pthread_mutex_init(&mutex);
pthread_cond_init(&condition, NULL);
} void MyWaitOnConditionFunction()
{
// Lock the mutex.
pthread_mutex_lock(&mutex); // If the predicate is already set, then the while loop is bypassed;
// otherwise, the thread sleeps until the predicate is set.
while(ready_to_go == false)
{
pthread_cond_wait(&condition, &mutex);
} // Do work. (The mutex should stay locked.) // Reset the predicate and release the mutex.
ready_to_go = false;
pthread_mutex_unlock(&mutex);
}
这是第二个线程的
void SignalThreadUsingCondition()
{
// At this point, there should be work for the other thread to do.
pthread_mutex_lock(&mutex);
ready_to_go = true; // Signal the other thread to begin work.
pthread_cond_signal(&condition); pthread_mutex_unlock(&mutex);
}
最开始碰到了这个问题:使用conditions即可,为何还要使用一个ready_to_go变量呢?
这个问题在文档中写的很清楚,Due to the subtleties involved in implementing operating systems, condition locks are permitted to return with spurious success even if they were not actually signaled by your code. To avoid problems caused by these spurious signals, you should
always use a predicate in conjunction with your condition lock. The predicate is a more concrete way of determining whether it is safe for your thread to proceed. The condition simply keeps your thread asleep until the predicate can be set by the signaling
thread. 就是说使用condition目前实现时有一些问题,会产生spurious signals,因此要结合一个predicate,就是断言信号来确定,这里就是ready_to_go。
还有一个问题,就是为何两个线程都使用了同一个互斥锁,这样第一个线程使用锁时,岂不是第二个线程永远无法唤醒第一线程了么?
后来查看文档点击打开链接,知道了These functions atomically release mutex and cause the calling thread to block on the condition variable cond;。就是说调用函数pthread_cond_wait 会使当前线程释放互斥锁,然后被condition
variable阻塞。点击打开链接 pthread_cond_signalt会使持有condition variable的线程唤醒,然后这些(一个活多个)线程就会争抢互斥锁,争抢到互斥锁的就会继续执行,其他(如果有)线程就会被阻塞。至于为何在调用pthread_cond_signalt时需要加互斥锁呢?这是为了把改变spurious
signals的值和调用pthread_cond_signal做为原子操作来看待。
因此,在第二个线程的互斥锁释放后,第一个线程才会争抢互斥锁。
关于condition variable的理解的更多相关文章
- C++11中的mutex, lock,condition variable实现分析
本文分析的是llvm libc++的实现:http://libcxx.llvm.org/ C++11中的各种mutex, lock对象,实际上都是对posix的mutex,condition的封装.不 ...
- C++关于Condition Variable
#include <condition_variable> #include <mutex> #include <future> #include <iost ...
- 关于Condition Variable的一些思考
可能大家都使用过condition variable(之后称cv),一些博客也对cv做了介绍,但是有的说的不完全正确,甚至有误导使用者的倾向,其实最合理的使用方式是查阅文档, 如果你英语还ok的话,h ...
- c++并发编程之条件变量(Condition Variable)
条件变量(Condition Variable)的一般用法是:线程 A 等待某个条件并挂起,直到线程 B 设置了这个条件,并通知条件变量,然后线程 A 被唤醒.经典的「生产者-消费者」问题就可以用条件 ...
- Condition Variable使用及其Thread Cancellation线程取消
条件变量Condition Variable的一般用法: 唤醒用法: struct { pthread_mutex_t mutex; pthread_cond_t cond; //whatever v ...
- 第8章 用户模式下的线程同步(4)_条件变量(Condition Variable)
8.6 条件变量(Condition Variables)——可利用临界区或SRWLock锁来实现 8.6.1 条件变量的使用 (1)条件变量机制就是为了简化 “生产者-消费者”问题而设计的一种线程同 ...
- [转] 条件变量(Condition Variable)详解
http://www.wuzesheng.com/?p=1668 条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法.举个简单的例子,应用程序A ...
- Spring:@Cacheable 中condition条件的理解
condition=false时,不读取缓存,直接执行方法体,并返回结果,同时返回结果也不放入缓存. ndition=true时,读取缓存,有缓存则直接返回.无则执行方法体,同时返回结果放入缓存(如果 ...
- 条件变量(Condition Variable)详解
条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法.举个简单的例子,应用程序A中包含两个线程t1和t2.t1需要在bool变量test_cond ...
随机推荐
- JavaScript资源大全
目录 前端MVC 框架和库 包管理器 加载器 打包工具 测试框架 框架 断言 覆盖率 运行器 QA 工具 基于 Node 的 CMS 框架 模板引擎 数据可视化 编辑器 UI 输入 日历 选择 文件上 ...
- ASP.NET MVC5+EF6搭建三层实例
一.创建项目解决方案 1.model层.BLL层.Dal层.Common层,都是类库 2.UI层使用MVC5 二.使用EF链接数据库 1.创建实体数据模型 2.选择来自数据库EF设计器 3.创建数据库 ...
- ASP.NET Core开发-使用Nancy框架
Nancy简介 Nancy是一个轻量级的独立的框架,下面是官网的一些介绍: Nancy 是一个轻量级用于构建基于 HTTP 的 Web 服务,基于 .NET 和 Mono 平台,框架的目标是保持尽可能 ...
- Application对象、Session对象、Cookie对象、Server对象初步认识
Application对象:记录应用程序参数的对象 用于共享应用程序级信息,即多个用户共享一个Application对象.在第一个用户请求ASP.NET文件时,将启动应用程序并创建Applicatio ...
- 做10年Windows程序员与做10年Linux程序员的区别
如果一个程序员从来没有在linux,unix下开发过程序,一直在windows下面开发程序, 同样是工作10年, 大部分情况下与在linux,unix下面开发10年的程序员水平会差别很大.我写这篇文章 ...
- C#的变迁史 - C# 2.0篇
在此重申一下,本文仅代表个人观点,如有不妥之处,还请自己辨别. 第一代的值类型装箱与拆箱的效率极其低下,特别是在集合中的表现,所以第二代C#重点解决了装箱的问题,加入了泛型.1. 泛型 - 珍惜生命, ...
- MySQL: LEAVE Statement
https://www.techonthenet.com/mysql/loops/leave.php This MySQL tutorial explains how to use the LEAVE ...
- 图-最短路径-Dijktra(迪杰斯特拉)算法
1. 迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉算法于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题.迪杰斯特拉算法主要特点是以起始 ...
- CRC编码
一.循环冗余码校验英文名称为Cyclical Redundancy Check,简称CRC. 它是利用除法及余数的原理来作错误侦测(Error Detecting)的.实际应用时,发送装置计算出CRC ...
- JS中跨域和沙箱的解析
先来直接分析源码,如下: <!DOCTYPE HTML><html><head> <meta charset="UTF-8"/> & ...