自学内容网 自学内容网

<mutex>注释3:全局 lock ()、try_lock (),

(15) 可以获取多个锁而不会陷入死锁的 全局函数 lock ( , ) ,实现的依赖的核心函数是 mutex . try_lock () :

template <class... _LockN>  // 该函数非常复杂,略,以后补充。但意思目前已经到了
int _Lock_attempt(const int _Hard_lock, _LockN&... _LkN) {  return 3;  } 

template <class _Lock0, class _Lock1> // 返回值的意思是,若加锁失败,则需要尝试重新加锁,故返回 true。
bool _Lock_attempt_small(_Lock0& _Lk0, _Lock1& _Lk1)  // 所以,若加锁成功则本函返回 false
{   // 尝试锁定2个锁,首先锁定_Lk0,然后尝试锁定_Lk1。返回是否再次trv
    // attempt to lock 2 locks, by first locking _Lk0, and then trying to lock _Lk1 
    // returns whether to try again。

    _Lk0.lock();
    _TRY_BEGIN           //  try {
    if (_Lk1.try_lock()) //     if (_Lk1.try_lock()) // 本函加锁成功返 T,锁忙碌返 F
        return false;    //         return false;

    _CATCH_ALL           //  } catch (...) {   // 也可能没有错误,捕捉不到错误,不需终止进程
    _Lk0.unlock();       //     _Lk0.unlock();
    _RERAISE;            //     throw;
    _CATCH_END           //  }

    _Lk0.unlock();       //  因为加锁失败,获得的 LK0 锁也释放掉
    _STD this_thread::yield(); // // 使本线程让出 CPU
    return true;         // true 表示本线程再次获得运行时需再次尝试获取这俩锁
}

template <class _Lock0, class _Lock1, class _Lock2, class... _LockN>
void _Lock_nonmember1(_Lock0& _Lk0, _Lock1& _Lk1, _Lock2& _Lk2, _LockN&... _LkN)
{   // 函数重载的复杂情况 lock 3 or more locks, without deadlock
    int _Hard_lock = 0;
    while (_Hard_lock != -1) 
        _Hard_lock = _Lock_attempt(_Hard_lock, _Lk0, _Lk1, _Lk2, _LkN...);
}

template <class _Lock0, class _Lock1> // 这是重载的简单情况
void _Lock_nonmember1(_Lock0& _Lk0, _Lock1& _Lk1)
{   // 锁 2 锁,没有死锁,特殊情况下更好的 codegen 和 redu 通用元编程
    while ( _Lock_attempt_small(_Lk0, _Lk1) && _Lock_attempt_small(_Lk1, _Lk0)) {}  
    // 函数 _Lock_attempt_small 加锁成功则返回 false ,加锁失败返回 true
}

template <class _Lock0, class _Lock1, class... _LockN> // lock multiple locks, without deadlock
void lock(_Lock0& _Lk0, _Lock1& _Lk1, _LockN&... _LkN) // 锁定多个锁,无死锁
{   //看源码,本函只有在获取了所有锁之后,才会返回。
    _Lock_nonmember1(_Lk0, _Lk1, _LkN...);
}   //本函数的实现灵魂是调用 mutex.try_lock(),该函数不会陷入睡眠等待

(16) 全局不阻塞线程拿到多个锁的函数 try_lock (…)本函尝试加锁成功,返回 -1 。锁忙碌则释放所有的锁,返回0 或 1:

template <class... _LockN>  // 此函数的调用链一如既往的复杂,暂时略。以后看情能看懂的话况再补充
int _Try_lock_range(const int _First, const int _Last, _LockN&... _LkN) { return -1; }

template <class _Lock0, class _Lock1, class _Lock2, class... _LockN>
int _Try_lock1(_Lock0& _Lk0, _Lock1& _Lk1, _Lock2& _Lk2, _LockN&... _LkN) 
{   // try to lock 3 or more locks
    return _Try_lock_range(0, sizeof...(_LockN) + 3, _Lk0, _Lk1, _Lk2, _LkN...);
}

template <class _Lock0, class _Lock1>  // 函数的重载
int _Try_lock1(_Lock0& _Lk0, _Lock1& _Lk1) 
{
    if (!_Lk0.try_lock())  // 此函数 try 加锁成功则返回 true,锁忙碌则返回 false
        return 0;

    _TRY_BEGIN              // try {
    if (!_Lk1.try_lock()) { //     if (!_Lk1.try_lock()) { 
        _Lk0.unlock();      //          _Lk0.unlock();
        return 1;           //          return 1;
    }                       //     }
    _CATCH_ALL              // } catch (...) { // 也可能没有错误,捕捉不到错误,不需终止进程
        _Lk0.unlock();      //     _Lk0.unlock();
    _RERAISE;               //     throw;
    _CATCH_END              // }

    return -1;
}

template <class _Lock0, class _Lock1, class... _LockN>
int try_lock(_Lock0& _Lk0, _Lock1& _Lk1, _LockN&... _LkN)
{   // try to lock multiple locks
    return _Try_lock1(_Lk0, _Lk1, _LkN...);
}   // 本函尝试加锁成功,返回 -1 。锁忙碌则释放所有的锁,返回0 或 1

(17)

(18)

(19)

(20)

谢谢


原文地址:https://blog.csdn.net/zhangzhangkeji/article/details/144070771

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!