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比赛中是一种常用的做法 ...
随机推荐
- UNIX网络编程读书笔记:UNIX域协议
概述 UNIX域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用API与在不同主机上执行客户/服务器通信所用的API(套接口API)相同.UNIX域协议可视为进程间通信 ...
- hadoop,hbase,hive安装全记录(转)
http://wenku.baidu.com/view/5eb3b4a6f90f76c661371abe.html 或http://blog.csdn.net/chengweipeng123/arti ...
- linux&shell
Linux经常使用命令 登录时显示信息放在/etc/motd和/etc/profile.d/xxx.sh motd放置字符串 profile.d下放置脚本文件 echo echo -e 处理特殊字符. ...
- [Swift A] - Using Swift with Cocoa and Objective-C--Mix and Match
Swift与Objective-C的兼容能力允许你在同一个工程中同时使用两种语言.你可以用这种叫做“mix and match”的特性来开发基于混合语言的应用.使用Swfit的最新特性--“mix a ...
- Java微信扫描支付模式二Demo ,整合官网直接运行版本
概述 场景介绍 用户使用微信“扫一扫”扫描二维码后,获取商品支付信息,引导用户完成支付. 详细 代码下载:http://www.demodashi.com/demo/13880.html 一.相关配置 ...
- DP SRM 661 Div2 Hard: ColorfulLineGraphsDiv2
Problem Statement Bob is going to create a graph with N nodes. The graph will be constructed in two ...
- How vacuum template0
[pg@h1 ~]$ vacuumdb --freeze template0 vacuumdb: could not connect to database template0: FATAL: dat ...
- apache绑定多个域名
在httpd.conf里, 1.把#NameVirtualHost *:80前的注释去掉2.ServerName 127.0.0.1 修改成ServerName 72.167.11.303.#Name ...
- moment
var now = moment(1410181234567)var formatted = now.format('YYYY-MM-DD HH:mm:ss')console.log(formatte ...
- 工作总结 表单提交中 Input 设置 disabled readonly
input框里面添加disabled属性之后,该内容就无法向上提交 需要的时候也可以再移除disabled readonly这个属性来禁止用户修改, 可以正常提交. Hiddent 隐藏 也可以正 ...