可以强制/检测到锁排序以防止死锁吗?
Can lock ordering be enforced / detected to prevent deadlocks?
我继承了一个历史悠久的大项目,我的任务是修复多年来报告的一堆死锁。
我理解一些死锁的本质,并且可以使用一些精心放置的Sleeps
和其他强制定时来一致地复制它们。
但是,修复死锁并不是那么简单。编写代码时没有使用任何关于锁定资源的策略。我可以为每个死锁手工设计解决方案,但大部分都归结为锁顺序的问题。
例如,Worker 1:
Acquires resource A
{
...
Acquires resource B
{
...
}
}
当worker 2执行此操作时:
Acquires resource B
{
...
Acquires resource A
{
...
}
}
所以我的问题是:在代码中检测和/或强制执行锁排序问题的最佳方法是什么?静态分析?是否有一种编译时的方法来检测这个(理想的)?或者我必须在运行时检测这类问题?
有一个查找潜在死锁的简单策略。如果一位代码锁定A,然后锁定B,而另一位代码锁定B,然后锁定A,就会发生死锁。如果它们在错误的时间这样做,就会发生死锁。如果他们在没有造成伤害的情况下这么做,就可能导致僵局。假设第一个代码是正确的,那么第二个代码就不应该尝试按照这个顺序使用锁(您必须决定哪个代码是错误的,哪个是正确的)。
为每个锁指定一个整数值。假设锁A = 100,锁B = 130。然后制定一个规则:当持有一个值为X的锁时,只有当它的值为Y> X时,才必须获取另一个锁。代码锁定B然后锁定a违反了条件。
显然,需要对所有锁进行一些封装来实际检查这一点。如果发现违反,必须决定是更改代码还是更改分配给锁的值,直到不再发现潜在的死锁为止。
相关文章:
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何在没有死锁和/或争用的情况下正确使用 std::mutex C++?
- 用C++中的std::condition_variable将线程置于死锁中会有风险吗
- 使用 std::async 时死锁,将来作为成员
- 如何调试读写器锁的死锁?
- 为什么在Visual Studio 2013上的std::this_thread::sleep_for上死锁
- localtime() 函数正在调用 ___lll_lock_wait_private(),这会使线程陷入死锁
- 如何重现 Boost 进程文档提示的死锁?
- 多线程Windows GUI应用程序中的死锁
- 为什么printf会导致与future.get的死锁,而cout则不会?
- C++中具有阻塞队列和障碍的死锁
- 死锁使用 std::mutex 来保护多个线程中的 cout
- 避免并发等待对象中的死锁
- 在VC++中从DLLMAIN内部调用D3D的CREATEDEVICE时,它会创建一个死锁(loaderlock?)。有没有办法克服这个问题?最终目标内
- 当用2个螺纹锁定时,将recursive_mutex死锁
- 程序在 C++11 中使用条件变量进入死锁
- 一个线程提升的死锁
- 单个生产者/多个消费者死锁
- 当被调用方法使用调用方已锁定的同一锁时,如何避免死锁
- 可以强制/检测到锁排序以防止死锁吗?