https://www.youtube.com/watch?v=13dFggo4t_I视频地址

实例1

考虑这样一个场景:存在一个全局队列deque,线程A向deque中推入数据(写),线程B从deque中取出数据(读).

deque这个资源对象就需要用mutex做访问控制,代码如下:

std::deque<int> q;
std::mutex mu; void func1() {
int ct = 10;
while (ct > 0) {
std::unique_lock<std::mutex> lock(mu);
q.push_front(ct);
lock.unlock();
std::this_thread::sleep_for(chrono::seconds(1));
ct --;
}
} void func2() {
int data = 0;
while (data != 1 ) {
std::unique_lock<std::mutex> lock(mu);
if (!q.empty()) {
data = q.back();
q.pop_back();
lock.unlock();
...
} else {
lock.unlock();
}
}
} int main() {
std::thread t1(func1);
std::thread t2(func2);
t1.join();
t2.join();
return 0;
}

线程t1中,循环向队列中推入数据,每次睡眠1秒;做为“生产者”.

线程t2中,不断地从队列中读出数据(先判断是否有数据);做为“消费者”.

存在一个问题:线程t2中,会先判断deque是否为空;如果为空,会执行unlock,然后马上进入下一次循环,造成busy waiting(反复频繁地判断某一状态是否为true).

一种解决方法如下:

void func2() {
...
} else {
lock.unlock();
std::this_thread::sleep_for(chrono::seconds(1));
}
}

在发现队列为空时睡眠一段时间time,可以一定程度上解决问题。

但是变量time设置成什么数值并不好确定;设置的过小,可能会回到busy waiting;设置的过大,会导致不能及时的获取数据

Condition variable

用条件变量可以很好的处理这个问题,让消费者不用“盲目等待”

std::deque<int> q;
std::mutex mu;
std::condition_variable cond; void func1() {
int ct = 10;
while (ct > 0) {
std::unique_lock<std::mutex> lock(mu);
q.push_front(ct);
lock.unlock();
cond.notify_one(); // wake up one waiting thread
// cond.notify_all(); // wake up all waiting threads
std::this_thread::sleep_for(chrono::seconds(1));
ct --;
}
} void func2() {
int data = 0;
while (data != 1 ) {
std::unique_lock<std::mutex> lock(mu);
cond.wait(lock, [](){ return !q.empty(); });
data = q.back();
q.pop_back();
lock.unlock();
}
}

生产者线程中,数据被推入deque后执行notify_one(),就可以唤醒某一个线程;类似于银行柜台叫号.

消费者线程中,只需要cond.wait(lock,...),睡眠等待,直到被“叫号”;睡眠等待过程中不占用cpu时间.(被唤醒时,第二个参数如果返回false会继续睡眠,为true则会往下执行)

注意这里cond.wait(lock)进入睡眠之前会先释放对lock的占用;被唤醒时会先占用mutex.

小结

condition_variable粗略的说,可能类似一个“唤醒服务”.

c++11多线程记录6:条件变量(condition variables)的更多相关文章

  1. [development][C] 条件变量(condition variables)的应用场景是什么

    产生这个问题的起因是这样的: ‎[:] ‎<‎tong‎>‎ lilydjwg: 主线程要启动N个子线程, 一个局部变量作为把同样的参数传入每一个子线程. 子线程在开始的十行会处理完参数. ...

  2. 深入解析条件变量(condition variables)

    深入解析条件变量 什么是条件变量(condition variables) 引用APUE中的一句话: Condition variables are another synchronization m ...

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

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

  4. 多线程编程中条件变量和的spurious wakeup 虚假唤醒

    1. 概述 条件变量(condition variable)是利用共享的变量进行线程之间同步的一种机制.典型的场景包括生产者-消费者模型,线程池实现等. 对条件变量的使用包括两个动作: 1) 线程等待 ...

  5. python多线程编程5: 条件变量同步-乾颐堂

    互斥锁是最简单的线程同步机制,Python提供的Condition对象提供了对复杂线程同步问题的支持.Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还 ...

  6. 练习生产者与消费者-PYTHON多线程中的条件变量同步-Queue

    以前练习过,但好久不用,手生,概念也生了, 重温一下.. URL: http://www.cnblogs.com/holbrook/tag/%E5%A4%9A%E7%BA%BF%E7%A8%8B/ ~ ...

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

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

  8. linux C++ 多线程使用pthread_cond 条件变量

    1. 背景 多线程中经常需要使用到锁(pthread_mutex_t)来完成多个线程之间的互斥操作. 但是互斥锁有一个明显到缺点: 只有两种状态,锁定和非锁定. 而条件变量则通过允许线程阻塞并等待另一 ...

  9. java多线程技术之条件变量

    上一篇讲述了并发包下的Lock,Lock可以更好的解决线程同步问题,使之更面向对象,并且ReadWriteLock在处理同步时更强大,那么同样,线程间仅仅互斥是不够的,还需要通信,本篇的内容是基于上篇 ...

随机推荐

  1. go中的字符串数值转化

    #string到int int,err := strconv.Atoi(string) #string到int64 int64, err := strconv.ParseInt(string, 10, ...

  2. 洛谷 P2815 IPv6地址压缩 题解

    P2815 IPv6地址压缩 题目背景 (友情提示:IPv6基础知识曾多次出现在NOIP初赛中)Internet Protocol,互联网协议,即为我们常说的IP.我们目前常说的IP主要指它的第四版, ...

  3. cBioPortal 数据库

    http://www.cbioportal.org/ 参考连接 http://www.geneseed.com.cn/page464?article_id=413

  4. quick player运行分析

    mac应用从AppController.mm源文件的applicationDidFinishLaunching函数启动: . - (void)applicationDidFinishLaunching ...

  5. fluent在运行时改变重力方向方法总结

    Fluent版本:19.0(其他版本应该也适用) 这里我们用一个简单的算例(同心环中的自然对流)来说明 算例来自<ANSYS Fluid Dynamics Verification Manual ...

  6. zabbix监控ESXI主机

    ESXI6.0默认SSH关闭的,打开SSH的方法如下图: SSH打开后,主机会有警报,关闭警报的方法如下图 esxcli system  snmp  set  --communities  publi ...

  7. [原创]App弱网测试方法介绍

    [原创]App弱网测试方法介绍 1 什么是弱网? 弱网就是在非正常网络状态下,用户在访问网络时遭遇到网络延迟或是丢包,造成使用产品时用户体验不佳或反感的场景. 2   为什么要进行弱网测试 简而方之, ...

  8. 油猴ajaxhook

    // ==UserScript== // @name ajaxHook // @namespace http://tampermonkey.net/ // @version 0.1 // @descr ...

  9. 利用python实现汉字转拼音

    安装:pip install pypinyin import pypinyin # 不带声调的(style=pypinyin.NORMAL) def pinyin(word): s = '' for ...

  10. 屏幕方向读取与锁定:Screen Orientation API(转)

    什么是 Screen Orientation API Screen Orientation API 为 Web 应用提供了读取设备当前屏幕方向.旋转角度.锁定旋转方向.获取方向改变事件的能力.使得特定 ...