16

根据thisunique_lock可以通过声明 a 用于递归锁定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 的文档是错误的?

蒂亚!!!

4

1 回答 1

31

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

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<std::recursive_mutex>,是的,你的实现是正确的。

于 2014-12-23T19:26:50.600 回答