C++ 为什么C+;中没有多个互斥锁的作用域锁+;0x还是Boost.Thread?

C++ 为什么C+;中没有多个互斥锁的作用域锁+;0x还是Boost.Thread?,c++,exception,boost,synchronization,c++11,C++,Exception,Boost,Synchronization,C++11,C++0x线程库或Boost.thread定义非成员变量模板函数,用于锁定所有锁,避免死锁 template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...); 这意味着我们需要使用其他机制作为try-catch块来生成异常安全的代码,或者自己在多个互斥体上定义自己的作用域锁,甚至这样做 { std::lock(l1,l2); std::unique_lock lk1(l1,

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

template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
这意味着我们需要使用其他机制作为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
}
为什么该标准没有在同一类型的多个互斥锁上包含作用域锁,例如

{
  std::array_unique_lock<std::mutex> lk(l1,l2);
  // do some thing
  // unlock l1 l2 on destruction of lk
}
{
std::数组\唯一\锁lk(l1,l2);
//做点什么
//销毁lk时解锁l1 l2
}
或者互斥体的元组

{
  std::tuple_unique_lock<std::mutex, std::recursive_mutex> lk(l1,l2);
  // do some thing
  // unlock l1 l2 on destruction of lk
}
{
std::tuple_unique_lock lk(l1,l2);
//做点什么
//销毁lk时解锁l1 l2
}
设计有什么问题吗


更新:标准中的说明

template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
模板无效锁(L1&,L2&,L3&…);
要求:每个模板参数类型都应满足互斥体要求,除非调用try_u-lock()可能引发异常。[注:当适当实例化时,unique_lock类模板满足这些要求。-结束注]

效果:通过对每个参数调用lock()、try_lock()或unlock()来锁定所有参数。调用顺序不应导致死锁,但在其他方面未指定。[注意:必须使用死锁避免算法,如try和backoff,但未指定特定算法以避免过度约束实现。-结束注意]如果对lock()或try_lock()的调用引发异常,则应对调用lock()或try_lock()锁定的任何参数调用unlock()



我已经接受了答案。我知道主要原因是没有足够的时间来改进C++0x线程库。我希望TR2将包含更多的内容。

构造一个锁定多个锁的对象不会比单独锁定它们更能避免死锁。你不能同时锁两把锁。。除非您使用两个线程,否则哪种类型的线程都不符合这一点。即使你把它们放在同一句话中,这也是正确的。

我认为,通过提供延迟锁定(和采用锁定),预期使用将像你的第二个例子一样,或者更像:

 std::unqiue_lock ul1(l1, std::deferred);
 std::unique_lock ul2(l2, std::deferred);
 std::lock(ul1, ul2);
这是例外安全和所有的好东西


我当然不能假装了解设计师的想法,但我猜他们正在努力提供一套最小的便携式、安全的原语。作用域多锁类型就是这么多的积冰,如果在标准中需要指定和设计,或者在boost.thread中,需要实现积冰(当然,最终标准也必须关注实现,看看导出发生了什么)

好问题,我不明白为什么没有一些
作用域多锁(t…)
。事实上,在我看来
锁(…)
函数是不平衡的。我至少也希望有同等的
unlock(…)
。似乎添加此类功能的最佳位置是
lock\u-guard
类。其中,它可以构建多个可锁定的,并在销毁时解锁。而不是一堆模板类。@Grafik你是对的。解锁也应该在标准上。不同之处在于解锁(…)不能死锁。@Grafik关于是否最好将当前锁保护和唯一锁可变模板或添加可变的新类,我认为最好将它们分开,因为在大多数情况下,我们需要一次锁定互斥锁。对于一个互斥锁的常见情况,可变版本肯定会带来比解决方案更复杂的问题。请参阅标准。它使用了一种使用try_lock和unlock的算法,这有助于避免死锁,在两个线程使用相同的函数获取两个日志的情况下。这与OP自己锁定两个日志有什么不同?可能是我误解了这个问题,但我认为他是在暗示,通过拥有这样一个多锁结构,显然可以立即避免死锁,而不是一个接一个地锁定死锁。不,这是关于异常安全和RAII风格的多锁。阅读Boost.Thread文档或关于
lock()
的C++0x草稿。请阅读我在问题
export
上添加的锁(…)的效果是一个完全不同的类别,并且(可能)需要在编译器中进行重大的体系结构更改。你为什么认为它需要这么多糖霜?就已经给出的原语而言,应该只写一次。@Logan很抱歉,我犯了一个错误,使用的是采用而不是采用锁定。@gf,这是我的观点。就已经给出的原语而言,它只写了一次,这就是为什么它不需要在标准中,也不需要成为实现者的负担。@Logan我理解你的所有解释,至少对于std,更不用说旨在提出新工具进行实验的Boost了。顺便说一句,export可能是个坏例子,但我只是想强调一个观点,即无论原则上实现某个东西有多么简单、容易或明显,这并不是免费的,工作仍然必须在实践中进行。
 std::unqiue_lock ul1(l1, std::deferred);
 std::unique_lock ul2(l2, std::deferred);
 std::lock(ul1, ul2);