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. Numpy | 11 迭代数组

    NumPy 迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式. 迭代器最基本的任务的可以完成对数组元素的访问. 实例1:使用 arange() 函数创建一个 2x3 ...

  2. thymeleaf做if判定

    <div class="showing"> <h2>条件判断</h2> <p th:if="${testBoolean}&quo ...

  3. k8s实现灰度发布

    灰度发布在实际生产部署中是经常被使用的方式,常规的方法是手动从前端LB(负载均衡)上将后端服务器摘掉,然后,停服务,最后上传代码,完成软连接更新.在使用CI/CD工具时,这个过程变得自动化了,我们只需 ...

  4. ssl 原理简介

    要想弄明白SSL认证原理,首先要对CA有有所了解,它在SSL认证过程中有非常重要的作用.说白了,CA就是一个组织,专门为网络服务器颁发证书的,国际知名的CA机构有VeriSign.Symantec,国 ...

  5. Mongoose 多表(N个表)关联查询aggregate

    Mongoose 多表(N个表)关联查询概述 需求:文章(article),文章分类(articlecate),用户(user)这三个表之间的关系,一篇文章对应文章分类表中的某个类型,对应着用户表中的 ...

  6. hosts 屏蔽广告 定位

    hosts 屏蔽广告 定位 JS Miner 挖矿 百度全家桶的全天候定位记录 各类统计服务(仅屏蔽 JS.不屏蔽控制台) 常见下载劫持 360 和百度的部分软件下载 CNNIC 根证书劫持 http ...

  7. Python全栈工程师(Python3 所有基础内容 0-0)

    转发:https://www.cnblogs.com/ParisGabriel/p/9388030.html statements  语句print   输出quit()  退出exit() 退出ct ...

  8. JVM探究之 —— 类加载过程

    1. 类加载是什么 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 与那些在编译时需要进行连 ...

  9. tensorflow 预训练模型列表

    tensorflow 预训练模型列表 https://github.com/tensorflow/models/tree/master/research/slim Pre-trained Models ...

  10. JDBC 线程安全 数据库连接池

    jdbc 是线程安全的,但是,推荐一个线程用一个链接 JDBC is thread safe: It is quite OK to pass the various JDBC objects betw ...