(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 ...
随机推荐
- CentOS7_K8S安装指南
https://www.cnblogs.com/liu-shuai/articles/12177298.html 不能完全按照他来装,因为他装的是15.5的,15.5 有部分组件在阿里云镜像上没有,导 ...
- MySQL数据备份 mysqldump 详解
MySQL数据备份流程 1 打开cmd窗口 通过命令进行数据备份与恢复: 需要在Windows的命令行窗口中进行: l 开始菜单,在运行中输入cmd回车: l 或者win+R,然后输入cmd回车,即可 ...
- KeeWiDB:兼容Redis协议,领跑NoSQL
如果现在的我们离开了互联网,生活会是什么样子? 互联网++++,已经深刻渗透到人们的生活中. 不知道大家有没有想过?每一个互联网+结合的背后都是海量的存储需求.你查看的每一个商品.组建的每一个战队.阅 ...
- Fluentd 简明教程
转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247491814&idx=1&sn=3b0f1a3477 ...
- Kubernetes Operator: Operator
Operator 就可以看成是 CRD 和 Controller 的一种组合特例,Operator 是一种思想,它结合了特定领域知识并通过 CRD 机制扩展了 Kubernetes API 资源,使用 ...
- ES小知识点
elasticsearch.yml配置文件 network.host: _site_ # network.host设置为"_site_",表明它绑定到我们的本地电脑的IP地址 di ...
- SpringCloud组件编写Dockerfile文件模板
在组件根目录下的Dockerfile文件 # Dockerfile文件内容 FROM idocker.io/jre:1.8.0_212 #自定义的基础镜像 VOLUME /tmp # 挂载目录 ADD ...
- 监控elasticsearch
转载自:https://cloud.tencent.com/developer/article/1655489 注意:上半截跟下半截是采用的不同的方式,建议采用下半截的方式,上半截的方式据说获取不到数 ...
- 220726 T2 Multisets (思维)
题目描述 我们说一个可重集 AA 比可重集 BB 小,当且仅当对于两个可重集中出现次数不同的最小元素 xx ,元素 xx 在 AA 中出现次数更多. 例如,可重集 {1,2,3}1,2,3 就比可重集 ...
- GTID主从
GTID主从 目录 GTID主从 GTID概念介绍 GTID工作原理 GTID主从配置 GTID概念介绍 GTID即全局事务ID (global transaction identifier), 其保 ...