<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的理解的更多相关文章

  1. C++11中的mutex, lock,condition variable实现分析

    本文分析的是llvm libc++的实现:http://libcxx.llvm.org/ C++11中的各种mutex, lock对象,实际上都是对posix的mutex,condition的封装.不 ...

  2. C++关于Condition Variable

    #include <condition_variable> #include <mutex> #include <future> #include <iost ...

  3. 关于Condition Variable的一些思考

    可能大家都使用过condition variable(之后称cv),一些博客也对cv做了介绍,但是有的说的不完全正确,甚至有误导使用者的倾向,其实最合理的使用方式是查阅文档, 如果你英语还ok的话,h ...

  4. c++并发编程之条件变量(Condition Variable)

    条件变量(Condition Variable)的一般用法是:线程 A 等待某个条件并挂起,直到线程 B 设置了这个条件,并通知条件变量,然后线程 A 被唤醒.经典的「生产者-消费者」问题就可以用条件 ...

  5. Condition Variable使用及其Thread Cancellation线程取消

    条件变量Condition Variable的一般用法: 唤醒用法: struct { pthread_mutex_t mutex; pthread_cond_t cond; //whatever v ...

  6. 第8章 用户模式下的线程同步(4)_条件变量(Condition Variable)

    8.6 条件变量(Condition Variables)——可利用临界区或SRWLock锁来实现 8.6.1 条件变量的使用 (1)条件变量机制就是为了简化 “生产者-消费者”问题而设计的一种线程同 ...

  7. [转] 条件变量(Condition Variable)详解

    http://www.wuzesheng.com/?p=1668 条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法.举个简单的例子,应用程序A ...

  8. Spring:@Cacheable 中condition条件的理解

    condition=false时,不读取缓存,直接执行方法体,并返回结果,同时返回结果也不放入缓存. ndition=true时,读取缓存,有缓存则直接返回.无则执行方法体,同时返回结果放入缓存(如果 ...

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

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

随机推荐

  1. Oracle Flashback和RMAN示例

    作者:Grey 原文地址:http://www.cnblogs.com/greyzeng/p/5346833.html 环境: Windows 10 专业版 Oracle Database 12c R ...

  2. 快速击键(MyEclipse编写的QuickHit项目)

    public class Level { private int levelNo;// 各级别编号 private int strLength;// 各级别一次输出字符串的长度 private int ...

  3. [锋利的JQ]-超链接提示效果

    关键知识点: 1.事件对象:当事件一旦被触发,事件对象便会创立.事件对象只能作用于该事件的事件处理程序. 2.认识了mousemove事件了连续触发执行的特性. 代码: HTML: <div c ...

  4. 【转载】async & await 的前世今生(Updated)

    async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们编程埋下了一些隐 ...

  5. SQL Server论坛楼层计算触发器

    代码: USE suya_dev GO IF EXISTS( SELECT * FROM sys.triggers WHERE name = N'BBS_Post_before_insert' ) D ...

  6. UML类图

    类 类图分三层,第一层显示类的名称,如果是抽象类,那就用斜体显示.第二层是类的特性,通常就是字段和属性.第三类是类的操作,通常是方法或行为.注意前面的符号,‘ +’表示public ,‘-’表示 pr ...

  7. 微信公众号入门学习1_使用C#,ASP.NET APIController如何公众号接入服务器并启动开发者模式

    前言:  本文是以微信公众号中的订阅号(个人)来进行简单介绍,本人也是刚刚开始学习,有不足之处,欢迎批评指正. 先粘贴2个帮助链接: 入门指引:http://mp.weixin.qq.com/wiki ...

  8. .NET使用ZXing.NET生成中间带图片的二维码

    很久之前就有写这样的代码了,只是一直没记录下来,偶然想写成博客. 把之前的代码封装成函数,以方便理解以及调用. 基于开源的 ZXing.NET 组件,代码如下: 先添加对ZXing.NET的引用,然后 ...

  9. 第一讲:WCF介绍

    代码 https://yunpan.cn/cPns5DkGnRGNs   密码:3913                                                         ...

  10. jquery内容选择器(匹配包含指定选择器的元素)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...