c++ std::lock与std::scoped_lock底层实现原理源码剖析

简介: std::lock用于同时获取多把锁(两把及两把以上)std::scoped_lock定义于c++ 17标准,是std::lock的RAII封装类以下代码纯来自msvc实现。

std::lock用于同时获取多把锁(两把及两把以上)

std::scoped_lock定义于c++ 17标准,是std::lock的RAII封装类

以下代码纯来自msvc实现

std::scoped_lock原型

在构造函数中调用std::lock,在析构函数中unlock

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...);
    }

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

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

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

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

lock函数原型

这里我画了一个流程图,std::lock调用层次_Lock_nonmember1->_Lock_attempt_small

如果不能将所有的锁全部获取就会将已经获取的锁全部释放后再次尝试获取

在这里插入图片描述

void lock(_Lock0& _Lk0, _Lock1& _Lk1, _LockN&... _LkN) {
   
    // lock multiple locks, without deadlock
    _Lock_nonmember1(_Lk0, _Lk1, _LkN...);
}

template <class _Lock0, class _Lock1>
void _Lock_nonmember1(_Lock0& _Lk0, _Lock1& _Lk1) {
   
   
    // lock 2 locks, without deadlock, special case for better codegen and reduced metaprogramming for common case
    while (_Lock_attempt_small(_Lk0, _Lk1) && _Lock_attempt_small(_Lk1, _Lk0)) {
   
    // keep trying
    }
}

template <class _Lock0, class _Lock1>
bool _Lock_attempt_small(_Lock0& _Lk0, _Lock1& _Lk1) {
   
   
    // attempt to lock 2 locks, by first locking _Lk0, and then trying to lock _Lk1 returns whether to try again
    _Lk0.lock();
    {
   
   
        _Unlock_one_guard<_Lock0> _Guard{
   
   _Lk0};
        if (_Lk1.try_lock()) {
   
   
            _Guard._Lk_ptr = nullptr;
            return false;
        }
    }

    _STD this_thread::yield();
    return true;
}
目录
相关文章
|
1月前
|
C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
存储 C语言 C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
30天前
|
C++
C++番外篇——虚拟继承解决数据冗余和二义性的原理
C++番外篇——虚拟继承解决数据冗余和二义性的原理
36 1
|
1月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
47 2
|
2月前
|
安全 C++
C++: std::once_flag 和 std::call_once
`std::once_flag` 和 `std::call_once` 是 C++11 引入的同步原语,确保某个函数在多线程环境中仅执行一次。
|
3月前
|
存储 算法 数据可视化
【C++】C++旅游管理系统(源码+论文)【独一无二】
【C++】C++旅游管理系统(源码+论文)【独一无二】
|
3月前
|
存储 数据可视化 C++
【C++】C++ 职工信息管理系统(源码)【独一无二】
【C++】C++ 职工信息管理系统(源码)【独一无二】
|
3月前
|
搜索推荐 数据处理 文件存储
【C++】C++ 培训报名系统 (源码+论文)【独一无二】
【C++】C++ 培训报名系统 (源码+论文)【独一无二】
|
3月前
|
存储 C++
【C++】C++公司人事管理系统(源码)【独一无二】
【C++】C++公司人事管理系统(源码)【独一无二】