关于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 ...
随机推荐
- 列表视图(ListView和ListActivity)
在ListView中显示网络图片 ImageView 类虽然有一个 setImageUri 方法,但不能直接接受一个由网络地址生成的uri作为参数从而显示图片,我们只好使用其 setImageBitm ...
- 《淘宝技术这十年》之LAMP架构的网站
本文节选自<淘宝技术这十年>一书,子柳(赵超)著,由电子工业出版社出版.作者的系列博文:从P1到P7--我在淘宝这7年 2003年4月7日,马云在杭州成立了一个神秘的组织.他叫来十位员工, ...
- [AngularJS] AngularJS系列(1) 基础篇
目录 什么是AngularJS? 为什么使用/ng特性 Hello World 内置指令 内置过滤器 模块化开发 一年前开始使用AngularJS(以后简称ng),如今ng已经出2了.虽说2已完全变样 ...
- IOS 回收键盘通用代码
感觉IOS的键盘回收好累,所以封装了一个通用一点的方法 -(IBAction)spbResignFirstResponder:(id)sender { // NSLogObj(sender); if ...
- asp.net应用程序生命周期
asp.net应用程序生命周期(流程文字描述版) 请求——>IIS——>ISAPI映射——>交给asp.net(即为IIS的扩展)——>通知Application类创建一个应用 ...
- 注意:DateTimePicker.Text不靠谱
这鸟属性把我害苦过,特此敬告一下大家.具体表现在: 获取时:在DateTimePicker.ValueChanged事件中,获取到的Text有可能是string.Empty!!!,特别当ValueCh ...
- Oracle命名规范
1.编写目的 使用统一的命名和编码规范,使数据库命名及编码风格标准化,以便于阅读.理解和继承. 2.适用范围 本规范适用于公司范围内所有以ORACLE作为后台数据库的应用系统和项目开发工作. 3.对象 ...
- Wijmo 2016年蓝图
2015年很快就过去了,这是 Wijmo 重要的一年,尤其是对 Wijmo5.脱离传统的小部件,重新写一套 JS 控件,现在看来这个决定是正确的.用 TypeScript 写 Wijmo5,意味着我们 ...
- JS疑难点和GC原理
js解析与序列化json数据(一)json.stringify()的基本用法: 对象有两个方法:stringify()和parse().在最简单的情况下,这两个方法分别用于把JavaScript对象序 ...
- Java集合源码分析(一)
Java集合工具包位于Java.util包下,包含了很多常用的数据结构,如数组.链表.栈.队列.集合.哈希表等.学习Java集合框架下大致可以分为如下五个部分:List列表.Set集合.Map映射.迭 ...