关于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 ...
随机推荐
- adb shell 查看系统属性(用来判断特殊的操作系统)
一般来讲,在android程序开发中进行需要判断设备类型和系统版本 1.设备类型判断(android.os.Build.MODEL) 比如判断属于Google Nexus 5,Nexus 7,MIUI ...
- java nio之SocketChannel
Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道.可以通过以下2种方式创建SocketChannel: 打开一个SocketChannel并连接到互联网上的某台服务器. ...
- 大数据下的Distinct Count(一):序
在数据库中,常常会有Distinct Count的操作,比如,查看每一选修课程的人数: select course, count(distinct sid) from stu_table group ...
- Elasticsearch聚合 之 DateRange日期范围聚合
相比于range聚合,date range就是范围可以由时间来指定. 例如: { "aggs":{ "range":{ "date_range&quo ...
- 检测IP地址的正则表达式
正则表达式: ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?) ((2[0-4]\d|25[0-5]|[01]?\d\ ...
- Spring MVC 对于@ModelAttribute 、@SessionAttributes 的详细处理流程
初学 Spring MVC , 感觉对于 @ModelAttribute 和 @SessionAttributes 是如何被Spring MVC处理的,这一流程不是很清楚, 经过Google资料,有了 ...
- EasyUI使用tree方法生成树形结构加载两次的问题
html代码中利用class声明了easyui-tree,导致easyUI解析class代码的时候先解析class声明中的easyui-tree这样组件就请求了一次url:然后又调用js初始化代码请求 ...
- SCC重新建图
Tarjan或Kosaraju算法[对每个点归类belong]求出SCC之后,对num_scc个SCC重新建图,针对不同问题,考虑重边的问题. //************************** ...
- 如何设计一个 App 的注册登录流程?
移 动设备发力之前的登录方式很简单:用户名/邮箱+密码+确认密码,所有的用户登录注册都是围绕着邮箱来做.随着移动设备和社交网络的普及,邮箱不再是唯 一,渐渐的出现了微博,QQ,微信等第三方登录方式,手 ...
- java一点小的知识点
1.在dos底下编译运行java文件时,若有包名,需要建立包名对应的文件夹,然后编译的时候写出包名:java.mypack.PackageDemo 2.代码中有包名的时候,自动创建文件夹并编译的方法: ...