首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++11/14/17中mutex系列区别

C++11/14/17中mutex系列区别

原创
作者头像
音视频牛哥
发布2022-06-16 11:22:21
1.1K0
发布2022-06-16 11:22:21
举报

C++11/14/17中提供的mutex系列类型如下:

互斥量

C++版本

作用

mutex

C++11

基本的互斥量

timed_mutex

C++11

timed_mutex带超时功能。在规定的等待时间内,没有获取锁,线程不会一直阻塞,代码会继续执行

recursive_mutex

C++11

递归锁,允许在同一个线程中同一个互斥量多次被 lock() ,用于可能被连续多次上锁(期间未解锁)的情况,效率要比mutex低std::mutex 及其变种不允许同一个线程对互斥量多次上锁,而 std::recursive_mutex 则允许

recursive_timed_mutex

C++11

带超时的,递归的,独占互斥量,允许同一个线程,同一个互斥量,多次被lock,用法和非递归的一样

shared_timed_mutex

C++14

具有超时机制的可共享互斥量

shared_mutex

C++17

shared_mutex的弟弟曾实现是操作系统提供的读写锁,在多线程对共享资源读且少许县城对共享资源写的情况下,shared_mutex比mutex效率更高写锁(排它锁):lock/unlock读锁(共享锁):lock_shared/unlock_shared

以上系列的对象都提供了加锁(lock)、尝试加锁(try_lock)和解锁(unlock)方法。

为了避免死锁,std::mutex.lock方法和std:mutex.unlock方法需要成对使用,如果一个函数中有很多出口,而互斥体对象又是需要在整个面数作用域被保护的资源,那么我们在编码时会因为忘记在某个出口处调用std::mutex.unlock 而造成死锁。这时可以通过RAII技术封装这两个接口,C++新标准也提为我们提供了类似的封装:

互斥量管理

C++版本

作用

lock_guard

C++11

基于作用于的互斥量管理,在需要对资源进行保护的小范围作用域内,应首先考虑使用std::lock_guard

unique_lock

C++11

unique_lock 是 lock_guard 的升级加强版,一个通用的互斥量锁定包装器,它允许延迟锁定,限时深度锁定,递归锁定,锁定所有权的转移以及与条件变量一起使用。

shared_lock

C++14

shared_lock可用于保护共享数据不被多个线程同时访问unique_lock专门管理“独占模式”,而shared_lock专门管理“共享模式”

scoped_lock

C++17

如果有多个mutex要同时lock,用scoped_lock。如果只要lock一个mutex,可以用lock_guard

如std::lock_guard:

void func()
{
  std::lock quard<std:nutex> quard(mymutex);
  //在这里放被保护的资源操作
}

mymutex 的类型是std:mutex,guard对象的构造函数会自动调用mymutex.lock 方法对 mymutex 进行加锁,在 guard 对象出了其作用域时,guard对象的析构函数会自动调用 mymutex.unlock 方法对 mymutex 进行解锁,简单来说:根据 RAII原则,在构造函数中上锁(创建即上锁),在析构函数中解锁(销毁即解锁)。需要注意的是:mymutex 生命周期必须长于func 函数的作用域。

多线程使用锁经验总结:

  1. 减少锁的使用次数,能不用锁尽量不用;
  2. 明确锁的范围;
  3. 减少锁的使用粒度,尽量减少锁的作用的临界区代码范围。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档