C++多线程:互斥变量 std::mutex
文章目录
- 描述
- 成员函数
- 总结
描述
- 头文件
<mutex>
- 使用
std::mutex <variable>
- 简介
mutex
是一种多线程变成中的同步原语,它能够让共享数据不被多个线程同时访问,它不支持递归得对互斥对象上锁 - 特点
- 用方线程从它成功调用 lock 或 try_lock 开始,到它调用 unlock 为止占有 mutex
- 线程占有 mutex 时,所有其他线程若试图要求 mutex 的所有权,则将阻塞(对于 lock 的调用)或收到 false 返回值(对于 try_lock )
- 调用方线程在调用 lock 或 try_lock 前必须不占有 mutex ,否则无法获取<mutex>变量
成员函数
构造函数
std::mutex::mutex
constexpr mutex() noexcept;(1) mutex( const mutex& ) = delete;(2)
(1)构造mutex实例,
mutex
实例构造完成之后是处于unlocked
状态
(2)mutex的拷贝构造函数是不存在的std::mutex::~mutex
析构函数
销毁互斥变量
若互斥为任何线程占有,或若任何线程在保有任何互斥的所有权时终止,则行为未定义赋值运算符,不存在
std::mutex::lock
锁定互斥。若另一线程已锁定互斥,则到 lock 的调用将阻塞执行,直至获得锁
错误发生时抛出 std::system_error ,包括底层操作系统阻止 lock 满足其规定的错误。在抛出任何异常的情况下,不锁定互斥。所以,直接使用mutex的lock成员是无处法处理异常的情况。#include <iostream> #include <chrono> #include <thread> #include <mutex>int g_num = 0; // protected by g_num_mutex 共享数据 std::mutex g_num_mutex;void slow_increment(int id) {for (int i = 0; i < 3; ++i) {g_num_mutex.lock();++g_num;std::cout << id << " => " << g_num << '\n';g_num_mutex.unlock();//chrono是C++的时间库,提供1s线程的休眠std::this_thread::sleep_for(std::chrono::seconds(1));} }int main() {//0号线程和1号线程交叉执行对全局变量g_num对累加操作,执行完成之后sleep 1秒std::thread t1(slow_increment, 0);std::thread t2(slow_increment, 1);t1.join();t2.join(); }
输出如下
0 => 1 1 => 2 0 => 3 1 => 4 0 => 5 1 => 6
std::mutex::try_lock
尝试锁定互斥。立即返回。成功获得锁时返回 true ,否则返回 false。
若此操作返回 true ,则同一互斥上的先前 unlock() 操作同步于(定义于 std::memory_order )它。注意若此操作返回 false ,则先前的 lock() 不与之同步#include <chrono> #include <mutex> #include <thread> #include <iostream> // std::coutstd::chrono::milliseconds interval(100);std::mutex mutex; int job_shared = 0; // 两个线程都能修改 'job_shared',// mutex 将保护此变量int job_exclusive = 0; // 只有一个线程能修改 'job_exclusive'// 不需要保护// 此线程能修改 'job_shared' 和 'job_exclusive' void job_1() {std::this_thread::sleep_for(interval); // 令 'job_2' 持锁while (true) {// 尝试锁定 mutex 以修改 'job_shared'if (mutex.try_lock()) {std::cout << "job shared (" << job_shared << ")\n";mutex.unlock();return;} else {// 不能获取锁以修改 'job_shared'// 但有其他工作可做++job_exclusive;std::cout << "job exclusive (" << job_exclusive << ")\n";std::this_thread::sleep_for(interval);}} }// 此线程只能修改 'job_shared' void job_2() {mutex.lock();std::this_thread::sleep_for(5 * interval);++job_shared;mutex.unlock(); }int main() {/*可以看到job1中的实现,使用的是try_lock获取锁,因为刚开始job1线程会进行100毫秒的休眠,所以cpu会先去执行job2,但是job2使用的是lock成员所以在job2中sleep 500毫秒的过程中执行job1时try_lock返回false,则执行exclusive输出.当job2获取不到锁,job1休眠结束之后释放锁,则job1重新获取锁成功*/std::thread thread_1(job_1);std::thread thread_2(job_2);thread_1.join();thread_2.join(); }
输出如下
job exclusive (1) job exclusive (2) job exclusive (3) job exclusive (4) job shared (1)
std::mutex::unlock
解锁mutex实例
使用前提是当前线程必须被mutex的实例锁定,否则改函数的调用是未定义的
注意,当前成员与lock()
成员,一般不直接调用,因为对异常情况的处理并不友好(程序锁定期间发生异常,进程就直接退出),所以一般与std::unique_lock 与 std::lock_guard 管理排他性锁 一起使用
具体使用实例可以参考如上两个代码。
总结
mutex互斥变量,并提供来了独占锁特性。为C++提供了多线程访问共享数据的保护措施,同时引入了像unique_lock
和lock_gurad
异常处理锁机制来规避mutex
的成员处理异常情况的不足。
C++多线程:互斥变量 std::mutex相关推荐
- C++多线程中互斥量std::mutex与模板类std::lock_guard
一. 互斥量std::mutex C++中通过实例化std::mutex创建互斥量实例,通过成员函数lock()对互斥量上锁,unlock()进行解锁.C++中与std::mutex相关的类(包括锁类 ...
- C++11多线程---互斥量、锁、条件变量的总结
关于互斥量std::mutex的总结 互斥量用于组成代码的临界区.C++的多线程模型是基于内存的,或者说是基于代码片段的,这和我们操作系统学习的临界区概念基本一致,但是与Golang不同,Golang ...
- linux的mutex状态查询命令,如何断言std :: mutex是否已锁定?
使用GCC 4.8.2(在Linux / Debian / Sid 64位上)或GCC 4.9(在C ++ 11中可用)-我有一些互斥锁 std::mutex gmtx; 实际上,它是static某个 ...
- 【C++】多线程互斥锁、条件变量
我们了解互斥量和条件变量之前,我们先来看一下为什么要有互斥量和条件变量这两个东西,了解为什么有这两东西之后,理解起来后面的东西就简单很多了!!! 先来看下面这段简单的代码: int g_num = 0 ...
- C++ 多线程:条件变量 std::condition_variable
文章目录 描述 使用 描述 头文件<condition_variable> 定义 class condition_variable; 简介 之前我们也已经介绍过了C++多线程中互斥变量存在 ...
- 【多线程】多线程锁住的是什么、std::lock_guard<std::mutex> locker(mutex_)
通常不直接使用 mutex,lock_guard更加安全, 更加方便. lock_guard简化了 lock/unlock 的写法, lock_guard在构造时自动锁定互斥量, 而在退出作用域时会析 ...
- 【多线程】1.条件变量--std::condition_variable
条件变量允许我们通过通知进而实现线程同步. 因此,您可以实现发送方/接收方或生产者/消费者之类的工作流. 在这样的工作流程中,接收者正在等待发送者的通知.如果接收者收到通知,它将继续工作. 1. st ...
- C++多线程:异步操作std::async和std::promise
文章目录 std::async 简介 使用案例 std::promise 简介 成员函数 总结 之前的文章中提到了C++多线程中的异步操作机制 C++ 多线程:future 异步访问类(线程之间安全便 ...
- std::atomic和std::mutex区别
std::atomic介绍 模板类std::atomic是C++11提供的原子操作类型,头文件 #include<atomic>.在多线程调用下,利用std::atomic可实现数 ...
最新文章
- mysql年月分表_MySQL之按月拆分主表并按月分表写入数据提高数据查询速度
- PHP7+Swoole/Nginx/Golang性能对比
- python中列表数据汇总和平均值_python的列表List求均值和中位数实例
- linux unix shell programming,UnixampLinux Shell Programming I.ppt
- putty远程登录ssh主机
- bash error 环境变量错误
- 《美团数据平台及数仓建设实践》(209页).PDF
- LAMP架构调优(六)——开启长链接
- html给图片加文字,如何给图片加上字
- python编辑器怎么放大字体_增大python字体的方法步骤
- Android font-awesome 4.2 icons png(包含holo-light和holo-dark)
- 皮克公式 Peake‘s theorem
- 华为路由器hilink怎么用_华为HiLink是什么?华为hilink智能联网怎么用
- JavaScript控制光标定位操作
- 如何阻止搜索引擎收录指定网页
- 时序分析基本概念介绍--Timing Arc
- 编程环境和软件工具安装手册
- 智能停车场[简易版]
- JAVA 获取某天、某周、某月、某年的开始时间和结束时间
- 探索 Flutter 模拟事件触发 | 开发者说·DTalk
热门文章
- PCB的EMC设计之PCB叠层结构
- GridView中HyperLinkField的链接使用JavaScript问题
- 深度解析VC中的消息(上)
- 基于三维点云数据的主成分分析方法(PCA)的python实现
- 如果有的明星不会使用计算机,盘点娱乐圈不会用电脑手机的10大原始明星:最后一位出书都是手写...
- mysql 数字区间_币投君0904丨数字货币暴跌原因何在
- python最新版本 效率_Python:迭代列表与dict项目效率
- Keil C语言数据类型,KeilC的指针类型
- 第52章,bitmap图像处理(从零开始学android),第52章、Bitmap图像处理(从零开始学Android)...
- Keras ImageDataGenerator用于数据扩充/增强的原理及方法