是否有一种简单的定时锁定算法可以避免多个互斥锁上的死锁?
C++0x 线程库或 Boost.thread 定义了一个非成员可变参数模板函数,该函数一次锁定所有互斥体,有助于避免死锁。
template <class L1, class L2, class... L3>
void lock(L1&, L2&, L3&...);
同样的情况也适用于非成员变量模板函数 try_lock_until,它会锁定所有互斥体,直到达到给定时间,这有助于避免像 lock(...) 这样的死锁。
template <class Clock, class Duration,
class L1, class L2, class... L3>
void try_lock_until(
const chrono::time_point<Clock,Duration>& abs_time,
L1&, L2&, L3&...);
我有一个遵循与 Boost 函数 boost::lock(...) 相同设计的实现。但这是相当复杂的。
因为我可能会遗漏一些明显的东西,所以我想知道是否:
是否有一个简单的定时锁定算法可以避免多个互斥锁上的死锁?
如果不存在简单的实现,这是否可以证明 Boost 的提议是合理的?
PS 请避免发布复杂的解决方案。
注意:
- 我不想添加比 std::lock(...) 施加的约束更多的约束。
- std::lock(...) 并不能完全避免死锁。如果两个线程执行 std::lock(l1,l2) 和另一个线程执行 std::lock(l2,l1) ,它只是避免死锁。这足以避免很多僵局的情况。
C++0x thread library or Boost.thread define a non-member variadic template function that locks all mutex at once that helps to avoid deadlock.
template <class L1, class L2, class... L3>
void lock(L1&, L2&, L3&...);
The same can be applied to a non-member variadic template function try_lock_until, which locks all the mutex until a given time is reached that helps to avoid deadlock like lock(...).
template <class Clock, class Duration,
class L1, class L2, class... L3>
void try_lock_until(
const chrono::time_point<Clock,Duration>& abs_time,
L1&, L2&, L3&...);
I have an implementation that follows the same design as the Boost function boost::lock(...). But this is quite complex.
As I can be missing something evident I wanted to know if:
is there a simple timed lock algorithm avoiding deadlock on multiple mutexes?
If no simple implementation exists, can this justify a proposal to Boost?
P.S. Please avoid posting complex solutions.
Notes:
- I don't want to add more constraints than the ones std::lock(...) imposes.
- std::lock(...) doesn't avoid deadlock completely. It just avoid to have dead lock if two threads do std::lock(l1,l2) and the other std::lock(l2,l1). This is enough to avoid a lot of deadlock cases.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
经典(也是最好)的方法是定义互斥锁的锁定顺序,并确保一次持有多个锁定互斥锁的任何代码始终按该顺序锁定其互斥锁。这种方法在这里还不够吗?
The classic (and best) approach is to define an order in which mutexes are to be locked, and make sure that any code that holds more than one locked mutex at a time always locks its mutexes in that order. Is that approach insufficient here?
我能想到的最简单的方法是将所有互斥锁锁定为全局排序,尽管这需要认真思考正确性。实现是在创建时为互斥体提供一个序列号。然后,当有人将它们锁定为一组时,您可以按序列号对它们进行排序,然后继续按该顺序锁定。不需要特殊类型的锁,因为这将保证全局一致的锁顺序。
The easiest I can think of, although it would require some serious thought as to correctness, would be to do all mutex locking is a global ordering. The implementation would be to give mutexes a serial number on creation. Then when one locks them as a set you sort them by that serial number and proceed to lock in that order. There's no need for special kinds of locks, as this would guarantee a globally consistent lock order.