C++17 std::scoped_lock 实现

C++17 引入std::scoped_lock, 它是std::lock_guard的升级版本。

scoped_lock可以一次绑定多个mutex,保证不会死锁,

 如果有多个mutex要同时lock,用scoped_lock。 如果只要lock一个mutex,可以用lock_guard,不过更建议统一用升级过后的scoped_lock。

template< class... MutexTypes >
class scoped_lock;

(C++17 起)

类 scoped_lock 是提供便利 RAII 风格机制的互斥包装器,它在作用域块的存在期间占有一或多个互斥体。

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

scoped_lock 类不可复制

scoped_lock 代码实现

1. std::scoped_lock 是一个类模板,它有两个特化,

//类模板
_EXPORT_STD template <class... _Mutexes>
class _NODISCARD_LOCK scoped_lock { // class with destructor that unlocks mutexes
public:
    explicit scoped_lock(_Mutexes&... _Mtxes) : _MyMutexes(_Mtxes...) { // construct and lock
        _STD lock(_Mtxes...); //调用 lock, 防止死锁发生 
    }

    explicit scoped_lock(adopt_lock_t, _Mutexes&... _Mtxes) noexcept // strengthened
        : _MyMutexes(_Mtxes...) {} // construct but don't lock

    ~scoped_lock() noexcept {
        _STD apply([](_Mutexes&... _Mtxes) _STATIC_CALL_OPERATOR { (..., (void) _Mtxes.unlock()); }, _MyMutexes);
    }

    scoped_lock(const scoped_lock&)            = delete;
    scoped_lock& operator=(const scoped_lock&) = delete;

private:
    tuple<_Mutexes&...> _MyMutexes;
};

2. 对模板类型形参包只有一个类型情况的偏特化版本,等价与std::lock_guard

template <class _Mutex>
class _NODISCARD_LOCK scoped_lock<_Mutex> {
public:
    using mutex_type = _Mutex;

    explicit scoped_lock(_Mutex& _Mtx) : _MyMutex(_Mtx) { // construct and lock
        _MyMutex.lock();
    }

    explicit scoped_lock(adopt_lock_t, _Mutex& _Mtx) noexcept // strengthened
        : _MyMutex(_Mtx) {} // construct but don't lock

    ~scoped_lock() noexcept {
        _MyMutex.unlock();
    }

    scoped_lock(const scoped_lock&)            = delete;
    scoped_lock& operator=(const scoped_lock&) = delete;

private:
    _Mutex& _MyMutex;
};

3. 对类型形参包为空的情况的全特化,没有数据成员

template <>
class scoped_lock<> {
public:
    explicit scoped_lock() = default;
    explicit scoped_lock(adopt_lock_t) noexcept /* strengthened */ {}

    scoped_lock(const scoped_lock&)            = delete;
    scoped_lock& operator=(const scoped_lock&) = delete;
};

以上三种对应的实例代码

std::mutex m1,m2;

std::scoped_lock<std::mutex> lc{ m1 };                   // 匹配到偏特化版本  保有一个 std::mutex&
std::scoped_lock<std::mutex, std::mutex> lc2{ m1,m2 };   // 匹配到主模板     保有一个 std::tuple<std::mutex&,std::mutex&>
std::scoped_lock<> lc3; 

参考: https://mq-bai.gitbook.io/modern-cpp-concurrent-programming/md/xiang-xi-fen-xi/02scopedlock-yuan-ma-jie-xi

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值