(C++) 笔记 C++11 std::mutex std::condition_variable 的使用
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
int main() {
  constexpr size_t kLoopNum = 10;
  std::mutex mtx;
  std::condition_variable cv;
  bool ready_flag{false};
  std::thread thd_producer([&]() {
    for (size_t i = 0; i < kLoopNum; i++) {
      std::cout << "producer thread " << i << std::endl;
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
      if (!ready_flag) {
        std::unique_lock<std::mutex> lock;
        ready_flag = true;
        cv.notify_one();
      }
    }
  });
  std::thread thd_consumer([&]() {
    for (size_t i = 0; i < kLoopNum; i++) {
      std::cout << "consumer thread " << i << std::endl;
      std::unique_lock<std::mutex> lock;
      cv.wait(lock, [&]() {
        return !ready_flag;
      });
    }
  });
  thd_producer.join();
  thd_consumer.join();
}
输出信息:
producer thread 0
consumer thread 0
consumer thread 1
consumer thread 2
consumer thread 3
consumer thread 4
consumer thread 5
consumer thread 6
consumer thread 7
consumer thread 8
consumer thread 9
producer thread 1
producer thread 2
producer thread 3
producer thread 4
producer thread 5
producer thread 6
producer thread 7
producer thread 8
producer thread 9
使用解读
如下 a, b 用法等效
std::unique_lock <std::mutex> lck(mtx);
// cv.wait(lck, [&](){return ready;}); // (a)
while(!ready) cv.wait(lck);            // (b)
条件变量ready必须位于lock中,以保证内存序
cpp reference: conditional_variable
Even if the shared variable is atomic, it must be modified under the mutex in order to correctly publish the modification to the waiting thread.
Any thread that intends to wait on std::condition_variable has to
- acquire a std::unique_lockstd::mutex, on the same mutex as used to protect the shared variable
- either A
 2.1 check the condition, in case it was already updated and notified
 2.2 execute wait, wait_for, or wait_until. The wait operations atomically release the mutex and suspend the execution of the thread.
 2.3 When the condition variable is notified, a timeout expires, or a spurious wakeup occurs, the thread is awakened, and the mutex is atomically reacquired. The thread should then check the condition and resume waiting if the wake up was spurious.
 or B
 use the predicated overload of wait, wait_for, and wait_until, which takes care of the three steps above
C++11中的lock
- std::unique_lock
- std::lock_guard
- std::scoped_lock
- std::lock
C++11中的lock都属于资源自动管理(RAII)范畴。
unique_lock 在使用上比lock_guard更具有弹性,和 lock_guard 相比,unique_lock 主要的特色在于:
- unique_lock 不一定要拥有 mutex,所以可以透过 default constructor 建立出一个空的 unique_lock。
- unique_lock 虽然一样不可复制(non-copyable),但是它是可以转移的(movable)。所以,unique_lock 不但可以被函数回传,也可以放到 STL 的 container 里。
- 另外,unique_lock 也有提供 lock()、unlock() 等函数,可以用来加锁解锁mutex,也算是功能比较完整的地方。
- unique_lock本身还可以用于std::lock参数,因为其具备lock、unlock、try_lock成员函数,这些函数不仅完成针对mutex的操作还要更新mutex的状态。
conditional_variable的notidy
- cv.notify_one
- cv.notify_all
- std::notify_all_at_thread_exit(...)
参考
- C++11 并发指南五(std::condition_variable 详解)
- C++11 std::unique_lock与std::lock_guard区别及多线程应用实例
- cpp reference -- std::unique_lock
(C++) 笔记 C++11 std::mutex std::condition_variable 的使用的更多相关文章
- 基于std::mutex std::lock_guard std::condition_variable 和std::async实现的简单同步队列
		C++多线程编程中通常会对共享的数据进行写保护,以防止多线程在对共享数据成员进行读写时造成资源争抢导致程序出现未定义的行为.通常的做法是在修改共享数据成员的时候进行加锁--mutex.在使用锁的时候通 ... 
- 转 C++11 并发指南std::condition_variable详解
		之前看过,但是一直没有怎么用就忘了,转一篇别人的文字记录下来 本文将介绍 C++11 标准中 <condition_variable> 头文件里面的类和相关函数. <conditio ... 
- 【C/C++开发】C++11 并发指南三(std::mutex 详解)
		本系列文章主要介绍 C++11 并发编程,计划分为 9 章介绍 C++11 的并发和多线程编程,分别如下: C++11 并发指南一(C++11 多线程初探)(本章计划 1-2 篇,已完成 1 篇) C ... 
- C++11 并发指南三(std::mutex 详解)
		上一篇<C++11 并发指南二(std::thread 详解)>中主要讲到了 std::thread 的一些用法,并给出了两个小例子,本文将介绍 std::mutex 的用法. Mutex ... 
- C++11并发——多线程std::mutex (二)
		https://www.cnblogs.com/haippy/p/3237213.html Mutex 又称互斥量,C++ 11中与 Mutex 相关的类(包括锁类型)和函数都声明在 <mute ... 
- C++11 并发指南三(std::mutex 详解)(转)
		转自:http://www.cnblogs.com/haippy/p/3237213.html 上一篇<C++11 并发指南二(std::thread 详解)>中主要讲到了 std::th ... 
- C++11并发——多线程std::thread (一)
		https://www.cnblogs.com/haippy/p/3284540.html 与 C++11 多线程相关的头文件 C++11 新标准中引入了四个头文件来支持多线程编程,他们分别是< ... 
- C++ 11 多线程下std::unique_lock与std::lock_guard的区别和用法
		这里主要介绍std::unique_lock与std::lock_guard的区别用法 先说简单的 一.std::lock_guard的用法 std::lock_guard其实就是简单的RAII封装, ... 
- C++11:基于std::queue和std::mutex构建一个线程安全的队列
		C++11:基于std::queue和std::mutex构建一个线程安全的队列 C++中的模板std::queue提供了一个队列容器,但这个容器并不是线程安全的,如果在多线程环境下使用队列,它是不能 ... 
- C++11并发之std::mutex
		知识链接: C++11并发之std::thread 本文概要: 1. 头文件. 2.std::mutex. 3.std::recursive_mutex. 4.std::time_mutex. 5 ... 
随机推荐
- 利用京东云Web应用防火墙实现Web入侵防护
			摘 要 本指南描述如何利用京东云Web应用防火墙(简称WAF),对一个简单的网站(无论运行在京东云.其它公有云或者IDC)进行Web完全防护的全过程.该指南包括如下内容: 1 准备环境 1.1 在京东 ... 
- 华南理工大学 Python第4章课后小测-1
			1.(单选)下面程序的输出结果是: for c in "ComputerScience": print(c,end="") if c=="S" ... 
- Kubernetes后台数据库etcd:安装部署etcd集群,数据备份与恢复
			目录 一.系统环境 二.前言 三.etcd数据库 3.1 概述 四.安装部署etcd单节点 4.1 环境介绍 4.2 配置节点的基本环境 4.3 安装部署etcd单节点 4.4 使用客户端访问etcd ... 
- Java SE 4、继承
			继承 基本语法 class 子类 extends 父类{ } 子类就会自动拥有父类定义的属性和方法 父类又叫 超类,基类,子类又叫 派生类 细节 子类继承了所有的属性和方法,非私有的属性和方法可以在子 ... 
- Markdowm基础语法的使用(typora)
			Mackdown学习 一级标题:一个#加空格 回车 二级标题:两个#加空格 回车 以此类推... 一级标题(Ctrl+1) 二级标题(Ctrl+2) 三级标题(Ctrl+3) 四级标题(Ctrl+4) ... 
- CentOS7部署FastDFS+nginx模块
			软件下载 # 已经事先把所需软件下载好并上传到/usr/local/src目录了 https://github.com/happyfish100/libfastcommon/archive/V1.0. ... 
- 银河麒麟安装node,mysql,forever环境
			这就是国产银河系统的界面,测试版本是麒麟V10 链接: https://pan.baidu.com/s/1_-ICBkgSZPKvmcdy1nVxVg 提取码: xhep 一.传输文件 cd /hom ... 
- postman7种断言的使用
			导航:1.postman断言介绍2.状态码断言3.响应正文断言-包含4.响应正文断言-json字段5.响应头断言6.响应时间断言7.环境变量的断言 - - - - - - - - - 分割线 - - ... 
- 使用SqlDataReader对象从数据库中检索只读的数据。
			SqlDataReader对象每次从查询结果中读取一行到内存中,对于sql数据库,如果只需要顺序读取,可以优先选择SqlDataReader,其对数据库的读取速度非常快. 调用SqlDataReade ... 
- python基础作业2
			目录 编写一个用户认证装饰器 利用有参装饰器编写多种用户登录校验策略 利用递归函数依次打印列表中每一个数据值 获取用户权限并校验用户登录 编写一个用户认证装饰器 """ ... 
