如何检测循环呼叫
How to detect circular calls?
我一直在寻找死锁的原因以及避免和检测死锁的策略/工具。
另一个可能导致死锁的原因是阻塞函数以循环的方式调用其他阻塞函数,因此最终调用永远不会返回。
有时这很难发现,特别是在非常大的项目中。
那么,有没有什么工具/库/技术可以自动检测程序中的循环调用?
编辑:我主要用C和c++编写代码,所以,如果可能的话,给出适用于这些语言的主题的任何信息。
然而,这个话题似乎在SO中几乎没有涉及,所以其他语言的答案也可以。尽管如果有人发现相关的话,这些可能值得单独讨论
谢谢。
尝试获取相同的不可重入锁的循环(或递归)调用是最容易调试的阻塞场景之一:锁是确定性的,可以很容易地检查。当应用程序锁定时,启动调试器并查看堆栈跟踪,以了解持有哪些锁及其原因。
关于锁问题的一般解决方案…您可以查看一些提供互斥锁排序的库,并在尝试锁定无序互斥锁时检测。这种类型的解决方案可能是复杂的正确实施,但是一旦到位确保你不能进入死锁状态,因为它迫使所有进程获得锁在同一顺序(即如果持有锁拉过程,和它试图获取锁磅的顺序是正确的,那么它可以成功或锁,但无论过程持有锁磅不能试图锁拉排序约束不满足)。
如果你在Linux上,有两个Valgrind工具用于检测死锁和竞争条件:Helgrind, DRD。它们都是相互补充的,并且它们都值得检查线程错误。
在linux中你可以使用valgrind来检测死锁,使用--tool=helgrind
检测死锁(IMO)的最佳方法是编写一个测试程序,在30个不同线程中随机调用所有函数10000次。
如果你得到一个死锁,你可以使用VS2010的"并行堆栈"窗口。调试并行堆栈
->窗口->这个窗口将显示所有栈,这样您就可以找到死锁的方法。
线程安全的对象在调用其公共方法时应该是安全的,因此在使用它时不会出现死锁。
所以,我们的想法是锁定所有访问对象数据的公共方法。
除此之外,您还需要确保在类代码中永远不会调用公共方法。如果需要使用其中一个公共方法,那么将该方法设为私有,并将该私有方法包装为一个公共方法,该公共方法锁定并调用该方法。
如果你想要更好的锁粒度,你可以为每个部分创建有自己锁的对象,并像我建议的那样锁定它。然后使用封装将这些类组合成一个类。
的例子:
class Blah {
MyData data;
Lock lock;
public:
DataItem GetData(int index)
{
ReadLock read(lock);
return LocalGetData(index);
}
DataItem FindData(string key)
{
ReadLock read(lock);
DataItem item;
//find the item, can use LocalGetData() to get the item without deadlocking
return item;
}
void PutData(DataItem item)
{
ReadLock write(lock);
//put item in database
}
private:
DataItem LocalGetData(int index)
{
return data[index];
}
}
您可以找到一个构建调用图的工具,并检查图中的循环。
否则,有许多策略可以检测死锁或其他循环,但它们都依赖于某种支持基础设施。
存在死锁避免策略,必须分配锁优先级并根据优先级对锁进行排序。但是,这需要更改代码并执行标准。
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 为什么我的for循环不能正确获取argv
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 呼叫运营商<<临时
- while循环中while循环的时间复杂度是多少
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 为什么在这个代码结束循环中没有得到结束
- 在基于范围的for循环中使用结构化绑定声明
- OpenCL仅在循环呼叫时停止运行
- 如何防止游戏引擎更新循环中的多个声音呼叫
- 如何检测循环呼叫