【问题标题】:Can unique_lock be used with a recursive_mutex?unique_lock 可以与 recursive_mutex 一起使用吗?
【发布时间】:2014-12-23 18:50:00
【问题描述】:

根据thisunique_lock 可以通过声明std::unique_lock<std::recursive_mutex> 用于递归锁定,实际上编译良好。

但是,从检查代码(gcc 4.8.2 和 4.9.0)看来,unique_lock 并没有遵循 _Mutex.lock,而是实现了 lock 方法本身:

  void
  lock()
  {
if (!_M_device)
  __throw_system_error(int(errc::operation_not_permitted));
else if (_M_owns)
  __throw_system_error(int(errc::resource_deadlock_would_occur));
else
  {
    _M_device->lock();
    _M_owns = true;
  }

显然,这可以防止互斥锁的递归锁定,实际上尝试递归锁定会引发resource_deadlock_would_occur 异常。

我在这里遗漏了什么,这是一个错误,还是 unique_lock 的文档有误?

TIA!!!

【问题讨论】:

    标签: c++ multithreading locking recursive-mutex


    【解决方案1】:

    一个常见的错误是将mutexlock 混淆。 mutex 是一个可以在线程之间共享的对象(否则它将无用)。然而,锁本身并不是线程安全的对象。它不应该在线程之间共享。它通常是堆栈上的本地对象。例如:

    void foo()
    {
         std::unique_lock<std::mutex> lk(mut);  // mut comes from some other scope
         // mut locked here
         // ...
    }    // mut unlocked here
    

    在上面的示例中,如果foo() 被递归调用,您将有未定义的行为,因为您将递归锁定mut。在每次递归时,你都会得到一个新的unique_lock。所以unique_lock 不知道递归。如果确实需要递归调用foo(),则需要使用递归互斥锁,例如:

    void foo()
    {
         std::unique_lock<std::recursive_mutex> lk(mut);  // mut comes from some other scope
         // mut locked here
         // ...
    }    // mut unlocked here
    

    所以:是的,你可以使用std::unique_lock&lt;std::recursive_mutex&gt;,是的,你的实现是正确的。

    【讨论】:

    • 谢谢,霍华德!这让事情变得更加清晰。概率。阅读代码应该已经很明显了,但是 unique_lock 旨在分配在堆栈上的事实并没有引起我的注意。
    • 优秀的答案。答案很简单,概念也很简单,但是很容易把事情搞混!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 2018-02-16
    • 2020-06-30
    • 2014-11-15
    • 2011-12-07
    • 2011-11-20
    • 2011-06-02
    相关资源
    最近更新 更多