C++17.std::scoped_lock类,同时获取多个锁

本文介绍了C++17中的std::scoped_lock模板,它与std::lock_guard类似,用于管理多个互斥锁,防止死锁。通过std::lock()函数和std::scoped_lock,可以安全地在同一时间获取和释放多个锁。示例中展示了如何使用std::lock_guard和std::unique_lock来交换两个数据结构的内部值,确保在锁定和解锁过程中的安全性。
摘要由CSDN通过智能技术生成

template< class… MutexTypes > class scoped_lock;

C++17提供了新的RAII类模板std::scoped_lock<>。std:: scoped_lock<>和std::lock_guard<>完全等价,只不过前者是可变参数模板(variadic template),接收各种互斥型别作为模板参数列表,还以多个互斥对象作为构造函数的参数列表,它在作用域块的存在期间占有一或多个互斥。

创建 scoped_lock 对象时,它试图取得给定互斥的所有权。控制离开创建 scoped_lock 对象的作用域时,析构 scoped_lock 并以逆序释放互斥。若给出数个互斥,则使用免死锁算法,如同以 std::lock 。

scoped_lock 类不可复制。

假定我们需要同时获取多个锁,那么std::lock()函数和std::scoped_lock<>模板即可帮助防范死锁。

1、运用std::lock()函数和std::lock_guard<>类模板,进行内部数据的互换

  • C++标准库提供了std::lock()函数。它可以同时锁住多个互斥,而没有发生死锁的风险

  • 调用std::lock()锁定两个互斥①,并依据它们分别构造std::lock_guard实例②③。我们除了用互斥充当这两个实例的构造参数,还额外提供了std::adopt_lock对象,以指明互斥已被锁住,即互斥上有锁存在,std::lock_guard实例应当据此接收锁的归属权,不得在构造函数内试图另行加锁。

    //lock_guard
    std::lock(lhs.lock,rhs.lock);---  ①
    std::lock_guard<std::mutex> lock_a(lhs.lock, std::adopt_lock);---  ②
    std::lock_guard<std::mutex> lock_b(rhs.lock, std::adopt_lock);---swap(lhs.value,rhs.value);
    
    //unique_lock
    std::unique_lock<std::mutex> lock_a(lhs.lock,std::defer_lock);---  传入std::defer_lock实例,从而使互斥在完成构造时处于无锁状态
    std::unique_lock<std::mutex> lock_b(rhs.lock,std::defer_lock);---  ①实例std::defer_lock将互斥保留为无锁状态
    std::lock(lock_a,lock_b);---  ②到这里才对互斥加锁
    swap(lhs.value,rhs.value);
    
    

2、利用std::lock_guard<>类模板

  • C++17具有隐式类模板参数推导(implicit class template parameter deduction)机制,依据传入构造函数的参数对象自动匹配①,选择正确的互斥型别
    std::scoped_lock guard(lhs.lock,rhs.lock);---//等价于std::scoped_lock<std::mutex,std::mutex> guard(lhs.lock,rhs.lock);
    swap(lhs.value,rhs.value);
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值