为什么在C++ 0x或Boost.Thread中没有多个互斥锁的范围锁?

Vic*_*iba 6 c++ synchronization boost exception c++11

C++ 0x线程库或Boost.thread定义非成员可变参数模板函数,锁定所有锁定以避免死锁.

template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
Run Code Online (Sandbox Code Playgroud)

虽然此函数避免了死锁的帮助,但标准不包括用于编写异常安全代码的关联范围锁.

{
  std::lock(l1,l2);
  // do some thing
  // unlock li l2 exception safe
}
Run Code Online (Sandbox Code Playgroud)

这意味着我们需要使用其他机制作为try-catch块来制作异常安全代码或者在我们自己的多个互斥锁上定义我们自己的作用域锁定甚至这样做

{
  std::lock(l1,l2);
  std::unique_lock lk1(l1, std::adopted);
  std::unique_lock lk2(l2, std::adopted);
  // do some thing
  // unlock li l2 on destruction of lk1 lk2
}
Run Code Online (Sandbox Code Playgroud)

例如,为什么标准不包括相同类型的多个互斥锁的范围锁定

{
  std::array_unique_lock<std::mutex> lk(l1,l2);
  // do some thing
  // unlock l1 l2 on destruction of lk
}
Run Code Online (Sandbox Code Playgroud)

或互斥的元组

{
  std::tuple_unique_lock<std::mutex, std::recursive_mutex> lk(l1,l2);
  // do some thing
  // unlock l1 l2 on destruction of lk
}
Run Code Online (Sandbox Code Playgroud)

设计上有什么问题吗?


更新:标准描述

template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
Run Code Online (Sandbox Code Playgroud)

要求:每个模板参数类型应满足互斥锁要求,但对try_- lock()的调用可能会抛出异常.[注意:unique_lock类模板在适当实例化时满足这些要求. - 尾注]

效果:通过对每个参数的lock(),try_lock()或unlock()调用序列锁定所有参数.调用序列不应导致死锁,否则不指定.[注意:必须使用诸如try-and-back-off之类的死锁避免算法,但未指定特定算法以避免过度约束实现.-end note]如果对lock()或try_lock()的调用抛出异常,则应对通过调用lock()或try_lock()锁定的任何参数调用unlock().


我接受了答案.我知道主要原因是因为没有足够的时间来使C++ 0x Thread库更好.我希望TR2会包含更多内容.

Log*_*ldo 3

我认为通过提供 defer_lock_t (和 acquire_lock_t ),预期用法将类似于您的第二个示例,或者可能更像:

 std::unqiue_lock ul1(l1, std::deferred);
 std::unique_lock ul2(l2, std::deferred);
 std::lock(ul1, ul2);
Run Code Online (Sandbox Code Playgroud)

这是异常安全的,而且都是好东西。

我当然不能假装了解设计师的想法,但我的猜测是他们正在努力提供一组最小的可移植、安全的原语。作用域多重锁类型只是锦上添花,如果在标准中需要指定和设计,或者在 boost.thread 中,则需要实现(当然最终标准必须关心)实施也是如此,看看导出发生了什么)。