<mutex>注释2:#if defined( M ),#error “!“,函_Throw_C_error () 的输出,类 mutex、lock_guard、recursive_mutex 的源码

(9) # if defined ( )

在这里插入图片描述

(10) # error " Unsupported platform ! "

在这里插入图片描述
在这里插入图片描述

++ 再举例:

在这里插入图片描述

(11) 函 _Throw_C_error () 的输出形式 ,一些 STL 的库函数的执行结果需要被检查。正确则是可以的,错误则需要终止程序。那么报错后是什么样子的呢?

在这里插入图片描述

++ 报错结果如下:

在这里插入图片描述

(12) 类 mutex 与 类 lock_guard 的源码和注释。因为这里的互斥量太多,虽然在 STL 库里是在一个头文件,这里还是拆开展示,代码短也好阅读。因为 lock_guard 的源代码也不长,附在一块给出,同理还有 recursive_mutex 的源码与介绍 :

class condition_variable;
class condition_variable_any;

class _Mutex_base // base class for all mutex types 所有互斥类型的基类
{ 
private:
    friend condition_variable;
    friend condition_variable_any;

    char _Mtx_storage[80]; //这是一个简化定义,参考了内存对齐与数据量需求等方面

    // using _Mtx_t = struct _Mtx_internal_imp_t *;  返回值是一个指针
    _Mtx_t _Mymtx() { return reinterpret_cast<_Mtx_t>(&_Mtx_storage); }

public:
    // enum { _Mtx_plain=0x01, _Mtx_try=0x02, _Mtx_timed=0x04, _Mtx_recursive=0x100 };
    //           mutex : _Mutex_base {           mutex() : _Mutex_base(                ) {} };
    // recursive_mutex : _Mutex_base { recursive_mutex() : _Mutex_base( _Mtx_recursive ) {} };
    _Mutex_base(int _Flags = 0) noexcept
    {   // 可见,所有 mutex 互斥量默认具有 2_Mtx_try 标志 
        _Mtx_init_in_situ(_Mymtx(), _Flags | _Mtx_try);
    }   // _in_situ 应该是在原位初始化的意思

    // void __cdecl _Mtx_destroy_in_situ(_Mtx_t);
    ~_Mutex_base() { _Mtx_destroy_in_situ( _Mymtx() ); } // 析构函数

    _Mutex_base(const _Mutex_base&) = delete;            // 禁止 copy 构造函数
    _Mutex_base& operator=(const _Mutex_base&) = delete; // 禁止 copy 赋值运算符函数

    void lock() 
    {   // int __cdecl _Mtx_lock(_Mtx_t);当此函数返回 _Thrd_success 时才不报错
        _Check_C_return(  _Mtx_lock( _Mymtx() )  );
    }

    // int __cdecl _Mtx_unlock(_Mtx_t); 此函总返回 _Thrd_success
    void unlock() {    _Mtx_unlock(  _Mymtx()  );    }

    // enum { _Thrd_success, _Thrd_nomem, _Thrd_timedout, _Thrd_busy, _Thrd_error };
    bool try_lock()  
    {   // int __cdecl _Mtx_trylock( _Mtx_t );
        const auto _Res = _Mtx_trylock(  _Mymtx()  );

        switch (_Res) { // 只可以加锁成功或忙碌,否则报错终止进程。
        case _Thrd_success:     return true;
        case _Thrd_busy   :     return false;
        default           :     _Throw_C_error( _Res ); // 报错,终止进程
        }
    }

    using native_handle_type = void* ;
    native_handle_type native_handle() 
    {   // void* __cdecl _Mtx_getconcrtcs( _Mtx_t ); 
        return _Mtx_getconcrtcs(  _Mymtx()  ); 
    }
};

// mutex 与其父类 _Mutex_base 一模一样,没有做任何功能上的增加删除
class mutex : public _Mutex_base  
{ 
public:
    mutex() : _Mutex_base() {}
    mutex(const mutex&) = delete;   // 禁止了 copy 构造与 copy 赋值运算符函数
    mutex& operator=(const mutex&) = delete;
};

// indicates adopt lock 指示采用锁,具有此标志的构造函数将不再给 mutex 加锁
struct adopt_lock_t  {    explicit adopt_lock_t() = default; };

template <class _Mutex>
class lock_guard  // class with destructor that unlocks a mutex
{
private:
    _Mutex& _MyMutex;  // 数据成员是一个左值引用
public:
    using mutex_type = _Mutex;

    // construct and lock  在创建本 lock_guard 类型变量的时候,直接给上锁 
    explicit lock_guard(_Mutex& _Mtx) : _MyMutex(_Mtx) { _MyMutex.lock(); }
    
    // 构造函数的重载
    lock_guard(_Mutex& _Mtx, adopt_lock_t) : _MyMutex(_Mtx) {} // construct but don't lock

    ~lock_guard() { _MyMutex.unlock(); } // 出了本类型变量的作用域,析构函数中自动解锁

    lock_guard(const lock_guard&) = delete; // 禁止的 copy 构造与 copy 赋值运算符函数
    lock_guard& operator=(const lock_guard&) = delete;
};

// class for recursive mutual exclusion 递归互斥的类,
class recursive_mutex : public _Mutex_base  // 从源代码看,未对基类 _Mutex_base 做任何功能扩展
{   // 可在同一个线程里对一个锁多次加锁
public:
    recursive_mutex() : _Mutex_base( _Mtx_recursive ) {}

    recursive_mutex(const recursive_mutex&) = delete;  // 禁止了 copy 构造与 copy 赋值运算符函数
    recursive_mutex& operator=(const recursive_mutex&) = delete;

    bool try_lock() noexcept {    return _Mutex_base::try_lock();    }
};

(13) 给出这些锁的重复加锁的实验:

在这里插入图片描述

++ 可见,当一个线程里的多个函数处于同一个调用链上,可能都要操作共享数据,存在重复加锁的可能性时,需要用 recursive_mutex 才不会报错

在这里插入图片描述
在这里插入图片描述

(14)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值