使用unique_lock来执行可以通过lock_guard更快地完成的任务吗?

时间:2013-10-24 16:52:20

标签: c++ multithreading c++11 mutex

我对lock_guard存在的原因感到困惑。是吗:

  1. unique_lock更简单的界面?
  2. unique_lock更好的表现?
  3. 别的什么?

2 个答案:

答案 0 :(得分:24)

lock_guard可以使用一个状态单元实现:指向它已锁定的Mutex类型的指针或引用。

unique_lock必须同时保持该状态,并且知道当前是否已锁定,因为unique_lock可以拥有未锁定的Mutex。这意味着它必须至少具有bool额外状态。

lock_guard提供开销RAII锁定/解锁包装器,围绕获取和释放Mutex。基本上lock_guard意味着没有理由避免使用RAII来处理Mutex上的锁。

unique_lock只能达到零开销,如果可以说服编译器注意到你只能以lock_guard可以使用的方式使用它(即构造它,然后销毁它,而不是摆弄它)。

除了那些效率参数之外,看到lock_guard的程序员知道它将持续到范围结束而不必检查范围中的代码。看到unique_lock的程序员必须检查变量的所有使用情况,以了解是否属于这种情况。

但上述只是原因的一半。

另一半原因是因为C ++ 11的大部分线程库都基于boost库,这些库已经实现了一个主要独立于平台的线程库。 Boost同时具有lock_guardunique_lock,与C ++ 11版本的语义几乎相同。

因此,当boost线程库被标准化时,两者都被带入,并且没有人消除它们。

答案 1 :(得分:6)

你几乎在这里回答你自己的问题 - 1)和2)都是很好的理由。 std::lock_guard是一个简单的作用域锁定对象。诸如互斥锁获取超时之类的功能增加了互斥原语的复杂性,增加了执行操作所花费的时间以及互斥锁争用的可能性。那么为什么要为你不需要的东西买单?

无论是否有超时'try_locking'都是好的设计是另一个问题;像线程取消一样,C ++ 11没有实现的破坏设计。