(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 ...
随机推荐
- re.sub()用法
原文链接:https://blog.csdn.net/jackandsnow/article/details/103885422
- 跟羽夏学 Ghidra ——导航
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章 ...
- 类的常成员const
成员数据 以Human为例: 类中: 传统的初始化方式: ...
- Kubernetes 基本概念与组件
Kubernetes(简称 K8S) 的出现是容器化技术发展的必然结果,容器化是应用程序级别的虚拟化,运行单个内核上有多个独立的用户空间实例,这些实例就是容器:容器提供了将应用程序的代码.运行时.系统 ...
- SkyWalking 6.x 的架构图
可以看到主要由四部分组成: Agent(也叫Probe):代理或者探针,集成在被监测的应用中(SDK形式或者动态注入),采集应用的数据发送给后端(OAP). UI:自带的Web页面. OAP:后端,接 ...
- 使用docker-compose部署WordPress项目
创建空文件夹 假设新建一个名为 wordpress 的文件夹,然后进入这个文件夹. 创建 docker-compose.yml 文件 docker-compose.yml 文件将开启一个 wordpr ...
- 使用coverlet统计单元测试的代码覆盖率
单元测试是个好东西, 可以在一定程度上兜底 虽然写单元测试这件事情非常麻烦 但是好的单元测试可以显著提高代码质量, 减少bug, 避免无意中的修改导致其他模块出错 写测试用例的过程中, 靠人力去确保所 ...
- PAT (Basic Level) Practice 1020 月饼 分数 25
月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量.总售价.以及市场的最大需求量,请你计算可以获得的最大收益是多少. 注意:销售时允许取出一部分库存.样 ...
- CentOS部署MySQL
Linux上安装MySQL 第一步:确保服务器在最新的状态(可有可无) [root@chenstudy ~]# yum -y update 第二步:检测系统是否自带安装MySQL 我之前安装过MySQ ...
- A-卷积网络压缩方法总结
卷积网络的压缩方法 一,低秩近似 二,剪枝与稀疏约束 三,参数量化 四,二值化网络 五,知识蒸馏 六,浅层网络 我们知道,在一定程度上,网络越深,参数越多,模型越复杂,其最终效果越好.神经网络的压缩算 ...