可重入锁 std::recursive_mutex

文档:https://en.cppreference.com/w/cpp/thread/recursive_mutex

好奇它的实现。

找 clang 的 <mutex> 源码:https://github.com/llvm/llvm-project/blob/main/libcxx/include/mutex#L213

发现 lock 调用了 __libcpp_recursive_mutex_lock(&_m),其中 m 是 __libcpp_recursive_mutex_t。

看 __threading_support:https://github.com/llvm/llvm-project/blob/58a0dcee8009d6504ce05874e644eb1df1276a11/libcxx/include/__threading_support#L205

typedef pthread_mutex_t __libcpp_recursive_mutex_t;

int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
{
  return pthread_mutex_lock(__m);
}

int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
{
  return pthread_mutex_trylock(__m);
}

平平无奇。

最后发现关键来自于构造函数,或者说 init:

inline _LIBCPP_ALWAYS_INLINE
int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m)
{
    pthread_mutexattr_t attr;
    int __ec = pthread_mutexattr_init(&attr);
    if (__ec) return __ec;
    __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    if (__ec)
    {
        pthread_mutexattr_destroy(&attr);
        return __ec;
    }
    __ec = pthread_mutex_init(__m, &attr);
    if (__ec)
    {
        pthread_mutexattr_destroy(&attr);
        return __ec;
    }
    __ec = pthread_mutexattr_destroy(&attr);
    if (__ec)
    {
        pthread_mutex_destroy(__m);
        return __ec;
    }
    return 0;
}

初始化锁会调用 pthread_mutexattr_settype,为锁添加 PTHREAD_MUTEX_RECURSIVE 属性。

查看 die.net,这个属性来自 pthread,可能的实现是多一个计数,同一个线程每次 lock 计数+1,每次 unlock 计数-1.

https://linux.die.net/man/3/pthread_mutexattr_settype

PTHREAD_MUTEX_RECURSIVE
A thread attempting to relock this mutex without first unlocking it shall succeed in locking the mutex. The relocking deadlock which can occur with mutexes of type PTHREAD_MUTEX_NORMAL cannot occur with this type of mutex. Multiple locks of this mutex shall require the same number of unlocks to release the mutex before another thread can acquire the mutex. A thread attempting to unlock a mutex which another thread has locked shall return with an error. A thread attempting to unlock an unlocked mutex shall return with an error.


注:可重入锁被认为比较危险,因为会掩盖死锁的真相,详见:http://www.zaval.org/resources/library/butenhof1.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值