Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否有一种简单的定时锁算法可以避免多个互斥锁上的死锁?_C++_Boost_Synchronization_Timeout_C++11 - Fatal编程技术网

C++ 是否有一种简单的定时锁算法可以避免多个互斥锁上的死锁?

C++ 是否有一种简单的定时锁算法可以避免多个互斥锁上的死锁?,c++,boost,synchronization,timeout,c++11,C++,Boost,Synchronization,Timeout,C++11,C++0x线程库或Boost.thread定义一个非成员变量模板函数,该函数一次锁定所有互斥锁,有助于避免死锁 template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...); 模板 无效锁(L1&,L2&,L3&…); 这同样适用于非成员变量模板函数try_lock_until,该函数锁定所有互斥锁,直到达到给定的时间,这有助于避免类似锁的死锁(…) 模板 无效尝试锁定直到(

C++0x线程库或Boost.thread定义一个非成员变量模板函数,该函数一次锁定所有互斥锁,有助于避免死锁

template <class L1, class L2, class... L3> 
void lock(L1&, L2&, L3&...);
模板
无效锁(L1&,L2&,L3&…);
这同样适用于非成员变量模板函数try_lock_until,该函数锁定所有互斥锁,直到达到给定的时间,这有助于避免类似锁的死锁(…)

模板
无效尝试锁定直到(
常数计时:时间点和绝对时间,
L1&,L2&,L3&……);
我有一个实现,它遵循与Boost函数Boost::lock(…)相同的设计。但这相当复杂

因为我可能会错过一些明显的东西,我想知道:

是否有一种简单的定时锁算法可以避免多个互斥锁上的死锁?

如果不存在简单的实施方案,这是否可以证明有理由提出一项提振措施

注意:请避免发布复杂的解决方案


注:

  • 我不想添加比std::lock(…)强加的约束更多的约束
  • 锁(…)不能完全避免死锁。如果两个线程执行std::lock(l1,l2)和另一个std::lock(l2,l1),则只需避免死锁。这足以避免许多死锁情况
    经典的(也是最好的)方法是定义一个锁互斥体的顺序,并确保一次包含多个锁互斥体的任何代码总是按该顺序锁其互斥体。这种方法在这里还不够吗?

    我能想到的最简单的方法,尽管需要认真考虑正确性,但应该是将所有互斥锁都按全局顺序进行。实现方法是在创建互斥对象时给互斥对象一个序列号。然后,当一个人把它们作为一个集合锁定时,你可以按照序列号对它们进行排序,然后按照顺序锁定。不需要特殊类型的锁,因为这将保证全局一致的锁顺序。

    而且,如果唯一的解决方案是复杂的,它不会是提交给Boost的第一段复杂代码。@James我的实现遵循与Boost::lock相同的设计,这相当复杂。如果我们有使用现有接口的简单实现,这可以让用户使用。如果实现本身很复杂,那么最好在Boost上引入它(当然,如果功能被认为是有用的),因为用户不会自己实现它。std::lock(…)不会强制给互斥体下任何命令。所以我不想为try_lock_添加这个约束,直到(…)我猜“easest”是一个用词不当;-)我建议的排序在之前不属于
    try\u lock\u的一部分,而是互斥体(即
    Lockable
    )的一部分,因为常规互斥体标识符不足以进行排序,因为它们是重复使用的。因此,我的建议并不容易,因为它需要更改互斥实现。因此,从这个意义上讲,由于架构的变化,它可能被认为足够复杂,需要在Boost或STD端实现。您的应用程序中是否已经使用了此算法?我不知道全局排序如何不起作用。。特别是因为这正是杰里米·F.发布的答案,现在被接受了。我只是为您提供了具体的、高效的、模块化的、不容易出错的人工方式来实现完全相同的功能。不,我没用过这个。我提到过;-)我不使用这样的东西,因为我不会编写最终需要锁定许多资源的多线程程序,因为这是非常糟糕的多线程设计;-)锁(…)不强制给互斥对象下任何命令。所以我不想为try_lock_添加这个约束,直到(…)。锁(…)不能避免死锁。如果两个线程执行std::lock(l1,l2)和另一个std::lock(l2,l1),则只需避免死锁。这对于很多死锁情况来说已经足够了。我的感觉是,如果一个程序有线程a执行std::lock(l1,l2)和线程B执行std::lock(l2,l1),那么这个程序就是有缺陷的。检测和报告锁排序问题可能比尝试处理它更合适。让我们举个例子。两个帐户之间的转移函数锁定两个帐户。因此,如果线程是一个do传输(ac1,ac2)和线程是一个do传输(ac2,ac1),那么在传输中使用锁(…)可以避免死锁。
    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&...);