C++标准库之mutex
互斥锁有可重入、不可重入之分。C++标准库中用mutex表示不可重入的互斥锁,用recursive_mutex表示可重入的互斥锁。为这两个类增加根据时间来阻塞线程的能力,就又有了两个新的互斥锁:timed_mutex(不可重入的锁)、recursive_timed_mutex(可重入的锁)。
互斥锁单独使用时主要是为了使对共享资源的互斥使用,即同时只能有一个线程使用,以防止同时使用可能造成的数据问题。
C++标准库的所有mutex都是不可拷贝的,也不可移动。
mutex基本操作
上锁 lock 如果mutex未上锁,则将其上锁。否则如果已经其它线程lock,则阻塞当前线程。
上锁 try_lock 如果mutex未上锁,则将其上锁。否则返回false,并不阻塞当前线程。
解锁 unlock 如果mutex被当前线程锁住,则将其解锁。否则,是未定义的行为。
timed_mutex在mutex的基础上增加了以下两个操作
try_lock_for(duration) 如果timed_mutex未上锁,则将其上锁,否则阻塞当前线程,但最长只阻塞duration表示的时间段。
try_lock_until(time_point) 如果timed_mutex未上锁,则将其上锁,否则阻塞当前线程,但最长只会阻塞到time_point表示的时间点就不再阻塞。
try_lock_for/until可以检测到死锁的出现,这是目前想到的一种用途。
if(!try_lock_for(chrono::hours()))
{
throw "出现死锁!";
}
可重入的锁 recursive_mutex、recursive_timed_mutex与对应的mutex、timed_mutex操作一致。不同点在于,不可重入的锁在lock或try_lock一个已经被当前线程lock的锁时会导致死锁,而可重入的锁不会。
辅助类
template<class Mutex> class lock_guard;
lock_guard用于脱离lock_guard对象生存期后自动对互斥锁进行解锁操作。
explicit lock_guard(mutex_type &m);对象创建时执行 m.lock(),对象销毁时执行 m.unlock()
explicit lock_guard(mutex_type &m,adpot_lock_t tag);对象创建不执行lock,对象销毁时执行 m.unlock()。所以m应该是一个已经被当前线程lock的互斥锁。
template<class Mutex> class unique_lock;
unique_lock()noexcept;不管理任何锁。
explicit unique_lock(mutex_type &m);对象创建时执行 m.lock()。
unique_lock(mutex_type &m,try_to_lock_t tag);对象创建时执行 m.try_lock()。
unique_lock(mutex_type &m,defer_lock_t tag);对象创建时不进行上锁操作,m要满足没有被当前线程锁住的条件。
unique_lock(mutex_type &m,adopt_lock_t tag);对象创建时不进行上锁操作,m要满足已经被当前线程锁住的条件。
unique_lock(mutex_type &m,const duration & real_time);对象创建时执行 m.try_lock_for(real_time)。
unique_lock(mutex_type &m,const time_point & abs_time);对象创建时执行 m.try_lock_until(abs_time)。
unique_lock(unique_lock &&);移动构造
操作:unique_lock具备它所管理的锁的所有操作 lock、unlock、try_lock、try_lock_for、try_lock_until。
mutex_type *release(); 不再管理互斥锁。
void swap(unique_lock &);交换管理的互斥锁。
bool owns_lock() 用于探测unique_lock是否管理着一个互斥锁且其处于上锁状态。bool operate bool() 与owns_lock等同。
mutex_type * mutex();用于返回管理的互斥锁的指针,但仍对其进行管理。
在unique_lock销毁的时候,owns_lock为真才会执行unlock。
总的来说,lock_guard在时空间效率上比较高,但功能单一。unique_lock功能多,使用灵活,但时空间效率不如lock_guard。如果使用了辅助类来管理互斥锁,就不要直接操作锁了,否则容易引发混乱,产生BUG。
辅助函数
template <class Mutex1, class Mutex2, class... Mutexes>
int try_lock (Mutex1& a, Mutex2& b, Mutexes&... cde);
根据参数顺序对多个锁进行上锁,如果成功锁住所有锁,返回-1,返回值大于0表示失败的锁的位置号。
template <class Mutex1, class Mutex2, class... Mutexes>
void lock (Mutex1& a, Mutex2& b, Mutexes&... cde);
对多个锁进行上锁,该函数是阻塞的。另,它保证发生异常的情况下已经上锁的锁会被解锁。
C++标准库之mutex的更多相关文章
- Go 标准库 —— sync.Mutex 互斥锁
Mutex 是一个互斥锁,可以创建为其他结构体的字段:零值为解锁状态.Mutex 类型的锁和线程无关,可以由不同的线程加锁和解锁. 方法 func (*Mutex) Lock func (m *Mut ...
- Python标准库08 多线程与同步 (threading包)
Python主要通过标准库中的threading包来实现多线程.在当今网络时代,每个服务器都会接收到大量的请求.服务器可以利用多线程的方式来处理这些请求,以提高对网络端口的读写效率.Python是一种 ...
- STL笔记(6)标准库:标准库中的排序算法
STL笔记(6)标准库:标准库中的排序算法 标准库:标准库中的排序算法The Standard Librarian: Sorting in the Standard Library Matthew A ...
- 用CAS操作实现Go标准库中的Once
Go标准库中提供了Sync.Once来实现"只执行一次"的功能.学习了一下源代码,里面用的是经典的双重检查的模式: // Once is an object that will p ...
- Boost程序库完全开发指南——深入C++“准”标准库(第3版)
内容简介 · · · · · · Boost 是一个功能强大.构造精巧.跨平台.开源并且完全免费的C++程序库,有着“C++‘准’标准库”的美誉. Boost 由C++标准委员会部分成员所设立的Bo ...
- Python学习笔记16:标准库多线程(threading包裹)
Python主要是通过标准库threading包来实现多线程. 今天,互联网时代,所有的server您将收到大量请求. server要利用多线程的方式的优势来处理这些请求,为了改善网络port读写效率 ...
- go标准库的学习-io
参考https://studygolang.com/pkgdoc 导入方式: import "io" o包提供了对I/O原语的基本接口.本包的基本任务是包装这些原语已有的实现(如o ...
- 通过atomic_flag简单自旋锁实现简单说明标准库中锁使用的memory_order
在使用标准库中的加锁机制时,例如我们使用std::mutex,写了如下的代码(下面的代码使用condition_variable可能更合适) std::mutex g_mtx; int g_resNu ...
- C++标准库头文件<bits/stdc++.h>
在使用GNU GCC Compiler的时候,你可以包含一个头文件<bits/stdc++.h>,便可以使用C++中的各种标准库,而不用一个一个包含进来. 这在acm比赛中是一种常用的做法 ...
随机推荐
- 算法笔记_133:最大连续乘积子数组(Java)
目录 1 问题描述 2 解决方案 2.1 蛮力法 2.2 动态规划法 1 问题描述 给定一个浮点数组,任意取出数组中的若干个连续的数相乘,请找出其中乘积最大的子数组. 2 解决方案 2.1 蛮力法 ...
- 〖Linux〗关于Linux软件包安装位置、版本查询
1. 查询版本 aptitude show [软件] 2. 查询路径 dpkg -L [软件] whereis [软件] which [软件]
- Android系统源代码学习步骤
目前,互联网行业正在朝着移动互联网方向强劲地发展,而移动互联网的发展离不开背后的移动平台的支撑.众所周知,如今在移动平台市场上,苹果的iOS.谷歌的Android和微软的Windows Phone系统 ...
- kernel4.1 ioctl调用
在4.1内核中开发时遇到个奇怪的问题: 用户空间的ioctl无法调用到内核空间的unlock_ioctl 排查源码发现 546 int do_vfs_ioctl(struct file *filp, ...
- 树莓派/RaspberryPi Ubuntu远程连接
网络设置 设置Ubuntu主机跟树莓派在同一网段,树莓派设置静态IP地址: 查看/etc/network/interfaces的内容,其中有#For static IP, consult /etc/d ...
- 摘:"error LNK2019: 无法解析的外部符号 该符号在函数 中被引用" 错误原因
例如“error LNK2019: 无法解析的外部符号error LNK2001: 无法解析的外部符号“private: static struct _OVERLAPPED CUsbCom::g_Wr ...
- log4cpp基础测试
// log4cplus.cpp : 定义控制台应用程序的入口点.// #include "stdafx.h" #include <iostream>#include ...
- 使用多字节字符集的跨平台(PC、Android、IOS、WP)编码/解码方法
随着移动端的发展,跨平台已成为通讯架构设计的重要考虑因素,PC.Android.IOS.WP等跨多平台间的数据通讯,必然要解决字符编码/解码的问题. 多字节字符集MBCS不是跨平台的首选字符集,面向跨 ...
- springboot web 服务器选择
Spring Boot 揭秘与实战(五) 服务器篇 - 其他内嵌服务器 拓展链接 http://www.jianshu.com/p/9710585258fb 发表于 2017-01-03 | Spri ...
- 如何让maven 将工程依赖的jar 复制到WEB-INF/lib 目录下
1.在默认生命周期的compile阶段执行 maven-dependency-plugin:copy-dependencies命令即可:<plugin><groupId>org ...