互斥锁有可重入、不可重入之分。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的更多相关文章

  1. Go 标准库 —— sync.Mutex 互斥锁

    Mutex 是一个互斥锁,可以创建为其他结构体的字段:零值为解锁状态.Mutex 类型的锁和线程无关,可以由不同的线程加锁和解锁. 方法 func (*Mutex) Lock func (m *Mut ...

  2. Python标准库08 多线程与同步 (threading包)

    Python主要通过标准库中的threading包来实现多线程.在当今网络时代,每个服务器都会接收到大量的请求.服务器可以利用多线程的方式来处理这些请求,以提高对网络端口的读写效率.Python是一种 ...

  3. STL笔记(6)标准库:标准库中的排序算法

    STL笔记(6)标准库:标准库中的排序算法 标准库:标准库中的排序算法The Standard Librarian: Sorting in the Standard Library Matthew A ...

  4. 用CAS操作实现Go标准库中的Once

    Go标准库中提供了Sync.Once来实现"只执行一次"的功能.学习了一下源代码,里面用的是经典的双重检查的模式: // Once is an object that will p ...

  5. Boost程序库完全开发指南——深入C++“准”标准库(第3版)

    内容简介  · · · · · · Boost 是一个功能强大.构造精巧.跨平台.开源并且完全免费的C++程序库,有着“C++‘准’标准库”的美誉. Boost 由C++标准委员会部分成员所设立的Bo ...

  6. Python学习笔记16:标准库多线程(threading包裹)

    Python主要是通过标准库threading包来实现多线程. 今天,互联网时代,所有的server您将收到大量请求. server要利用多线程的方式的优势来处理这些请求,为了改善网络port读写效率 ...

  7. go标准库的学习-io

    参考https://studygolang.com/pkgdoc 导入方式: import "io" o包提供了对I/O原语的基本接口.本包的基本任务是包装这些原语已有的实现(如o ...

  8. 通过atomic_flag简单自旋锁实现简单说明标准库中锁使用的memory_order

    在使用标准库中的加锁机制时,例如我们使用std::mutex,写了如下的代码(下面的代码使用condition_variable可能更合适) std::mutex g_mtx; int g_resNu ...

  9. C++标准库头文件<bits/stdc++.h>

    在使用GNU GCC Compiler的时候,你可以包含一个头文件<bits/stdc++.h>,便可以使用C++中的各种标准库,而不用一个一个包含进来. 这在acm比赛中是一种常用的做法 ...

随机推荐

  1. UNIX网络编程读书笔记:UNIX域协议

    概述 UNIX域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用API与在不同主机上执行客户/服务器通信所用的API(套接口API)相同.UNIX域协议可视为进程间通信 ...

  2. hadoop,hbase,hive安装全记录(转)

    http://wenku.baidu.com/view/5eb3b4a6f90f76c661371abe.html 或http://blog.csdn.net/chengweipeng123/arti ...

  3. linux&amp;shell

    Linux经常使用命令 登录时显示信息放在/etc/motd和/etc/profile.d/xxx.sh motd放置字符串 profile.d下放置脚本文件 echo echo -e 处理特殊字符. ...

  4. [Swift A] - Using Swift with Cocoa and Objective-C--Mix and Match

    Swift与Objective-C的兼容能力允许你在同一个工程中同时使用两种语言.你可以用这种叫做“mix and match”的特性来开发基于混合语言的应用.使用Swfit的最新特性--“mix a ...

  5. Java微信扫描支付模式二Demo ,整合官网直接运行版本

    概述 场景介绍 用户使用微信“扫一扫”扫描二维码后,获取商品支付信息,引导用户完成支付. 详细 代码下载:http://www.demodashi.com/demo/13880.html 一.相关配置 ...

  6. 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 ...

  7. How vacuum template0

    [pg@h1 ~]$ vacuumdb --freeze template0 vacuumdb: could not connect to database template0: FATAL: dat ...

  8. apache绑定多个域名

    在httpd.conf里, 1.把#NameVirtualHost *:80前的注释去掉2.ServerName 127.0.0.1 修改成ServerName 72.167.11.303.#Name ...

  9. moment

    var now = moment(1410181234567)var formatted = now.format('YYYY-MM-DD HH:mm:ss')console.log(formatte ...

  10. 工作总结 表单提交中 Input 设置 disabled readonly

    input框里面添加disabled属性之后,该内容就无法向上提交  需要的时候也可以再移除disabled readonly这个属性来禁止用户修改, 可以正常提交. Hiddent 隐藏  也可以正 ...