一、条件变量的引入

std::condition_variable 解决了死锁并且控制的资源的访问顺序二避免不必要的等待。当互斥操作不够用而引入的。比如,线程可能需要等待某个条件为真才能继续执行,而一个忙等待循环中可能会导致所有其他线程都无法进入临界区使得条件为真时,就会发生死锁。所以,condition_variable实例被创建出现主要就是用于唤醒等待线程从而避免死锁。std::condition_variable的 notify_one()用于唤醒一个线程;notify_all() 则是通知所有线程。

二、下面是一个引用的例子

假设想实现一个简单的消费者生产者模型,一个线程往队列中放入数据,一个线程往队列中取数据,取数据前需要判断一下队列中确实有数据,由于这个队列是线程间共享的,所以,需要使用互斥锁进行保护,一个线程在往队列添加数据的时候,另一个线程不能取,反之亦然。
一般的:

std::deque<int> q;
std::mutex mu; void function_1() {
int count = ;
while (count > ) {
std::unique_lock<std::mutex> locker(mu);
q.push_front(count);
std::cout << "t1 put a value : " << count << std::endl;
locker.unlock();
std::this_thread::sleep_for(std::chrono::seconds());
count--;
}
} void function_2() {
int data = ;
while (data != ) {
std::unique_lock<std::mutex> locker(mu);
if (!q.empty()) {
data = q.back();
q.pop_back();
locker.unlock();
std::cout << "t2 got a value from t1: " << data << std::endl;
}
else {
locker.unlock();
}
}
}
int main() {
std::thread t1(function_1);
std::thread t2(function_2);
t1.join();
t2.join();
return ;
}
std::this_thread::sleep_for(std::chrono::seconds(1));表示延时1s,所以这个生产的过程是很慢的;function_2函数是消费者,存在着一个while循环,只有在接收到表示结束的数据的时候,才会停止,每次循环内部,都是先加锁,判断队列不空,然后就取出一个数,最后解锁。所以说,在1s内,做了很多无用功!这样的话,单核CPU占用率会很高,可能达到100%。
// threadTest.cpp: 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <string>
#include <fstream>
#include <deque>
#include <condition_variable> using namespace std; std::deque<int> q;
std::mutex mu;
std::condition_variable cond; void function_1()
{
int count = ;
while (count>)
{
std::unique_lock<mutex> locker(mu);
q.push_back(count);
locker.unlock();
cond.notify_all();
std::this_thread::sleep_for(chrono::seconds());
count--;
} } void funciton_2()
{
int data = ;
while (data != )
{
std::unique_lock<mutex> locker(mu);
cond.wait(locker, [](){return !q.empty(); }); // while(q.empty()) {cond.wait(locker); }// Unlock mu and wait to be notified 等同写法
        data = q.back(); 
q.pop_back();
locker.unlock();
cout << "t2 get a value form t1 " << data << endl; }
} int main() {
thread t1(function_1);
thread t2(funciton_2);
t1.join();
t2.join();
std::getchar(); return ; }

多线程一----多线程的应用

多线程二----简单线程管理

多线程三----数据竞争和互斥对象

多线程四----死锁和防止死锁

多线程五----unick_lock和once_flag

多线程六----条件变量

多线程七----线程间通信

c++11の条件变量的更多相关文章

  1. C++11 条件变量

    C++11中的条件变量提供了用户等待的同步机制,在同步队列的应用中有很大的便利. 简单同步队列代码如下(SimpleSyncQueue.h): #ifndef SIMPLESYNCQUEUE_H #d ...

  2. c++11 条件变量 生产者-消费者 并发线程

    http://baptiste-wicht.com/posts/2012/04/c11-concurrency-tutorial-advanced-locking-and-condition-vari ...

  3. C++11 中的线程、锁和条件变量

    转自:http://blog.jobbole.com/44409/ 线程 类std::thread代表一个可执行线程,使用时必须包含头文件<thread>.std::thread可以和普通 ...

  4. C++11并发——多线程条件变量std::condition_variable(四)

    https://www.jianshu.com/p/a31d4fb5594f https://blog.csdn.net/y396397735/article/details/81272752 htt ...

  5. c++11中的线程、锁和条件变量

    void func(int i, double d, const string& s) { cout << i << ", " << d ...

  6. C++11并行编程-条件变量(condition_variable)详细说明

    <condition_variable >头文件主要包含有类和函数相关的条件变量. 包括相关类 std::condition_variable和 std::condition_variab ...

  7. Windows:C++11并发编程-条件变量(condition_variable)详解

    <condition_variable >头文件主要包含了与条件变量相关的类和函数.相关的类包括 std::condition_variable和 std::condition_varia ...

  8. APUE学习笔记——11 线程同步、互斥锁、自旋锁、条件变量

    线程同步     同属于一个进程的不同线程是共享内存的,因而在执行过程中需要考虑数据的一致性.     假设:进程有一变量i=0,线程A执行i++,线程B执行i++,那么最终i的取值是多少呢?似乎一定 ...

  9. c++11多线程记录6:条件变量(condition variables)

    https://www.youtube.com/watch?v=13dFggo4t_I视频地址 实例1 考虑这样一个场景:存在一个全局队列deque,线程A向deque中推入数据(写),线程B从deq ...

随机推荐

  1. InterlliJ Debug方式启动:method breakpoints may dramatically show down debugging

    使用idea在DEBUG的时候出现Method breakpoints may dramatically slow down debugging, 如图: 根据语义可能是断点打在方法上面了,导致在某个 ...

  2. Asp.Net SignalR - 持久连接类

    持久连接类 通过SignalR持久连接类可以快速的构建一个即时通讯的应用,上篇博文已经我们创建一个owin Startup类和一个持久连接类来完成我们的工作,然后在Startup类的Configura ...

  3. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2->新增模块管理界面导出功能(可按条件导出)

    导出功能在很多应用场景中都需要,RDIFramework.NET V3.2版本在模块管理界面新增了导出功能,方便管理员对所有配置的模块进行管理. 一.Web版模块管理导出功能 Web版本的模块导出功能 ...

  4. 只需要4步就可以将asp.net mvc变成SPA(单页面)应用,实现无刷新页面切换!

    SENNA.js Senna.js是一个超快速的单页面应用程序引擎,轻松构建基于Web的现代应用程序,只有大约8KB的JavaScript而没有任何依赖性.还提供非常酷炫的动画效果.想要详细了解的朋友 ...

  5. Haskell复习笔记(二)

    Haskell中的递归 递归就是定义函数以调用自身的方式,关于递归解决问题的实例有很多,如斐波那契数列,还有汉诺塔问题,递归也正是Haskell中用来解决循环问题的关键. 自定义maxinum函数 m ...

  6. 第34章 授予类型 - Identity Server 4 中文文档(v1.0.0)

    授权类型是指定客户端如何与IdentityServer交互的方式.OpenID Connect和OAuth2.0规范定义了以下授权类型: Implicit Authorization code Hyb ...

  7. Eclipse Ctrl+Space 无法工作的问题

    Window->preference->Keys 然后找到content Assist,然后重新设置为自己想要的Short cut 就好了

  8. Elasticsearch系列(4):基本搜索

    空搜索 搜索API的最基础的形式是没有指定任何查询的空搜索 ,它简单地返回集群中所有索引下的所有文档,如下命令: GET /_search 返回如下结果: 查询结果解释: 1,hits 返回结果中最重 ...

  9. 高效使用VSCode的9点建议

    在开源 IDE 市场,最近几年 Visual Studio Code(简称 VSCode)越来越流行.自从 2015 年对外发布后,根据 2018 年 Stack Overflow 的调查报告,有 3 ...

  10. Canvas:时钟

    这个时钟是将钟盘的圆心点移到了 canvas 画布中心点.以方便后面的方位计算 ctx.translate(width/2,height/2); 现定义一个圆盘来显出这个时钟的基本位置 ctx.sav ...