Ana*_*oge 8 delphi multithreading deadlock critical-section
我正在寻找一种方法来调试罕见的Delphi 7临界区(TCriticalSection)挂起/死锁.在这种情况下,如果一个线程正在等待一个关键部分超过10秒,我想生成一个报告,其中包含当前锁定关键部分的线程的堆栈跟踪以及无法执行的线程在等待10秒后锁定关键部分.如果引发异常或应用程序终止,则可以.
如果可能的话,我宁愿继续使用关键部分,而不是使用其他同步原语,但如果需要可以切换(例如获得超时功能).
如果工具/方法在IDE之外的运行时工作,这是一个奖励,因为这很难按需重现.在极少数情况下,我可以复制IDE内部的死锁,如果我尝试暂停以开始调试,IDE就会无所事事,并且永远不会进入我可以查看线程或调用堆栈的状态.不过,我可以重置正在运行的程序.
更新:在这种情况下,我只处理一个关键部分和2个线程,所以这可能不是锁定排序问题.我相信有一个不正确的嵌套尝试跨越两个不同的线程进入锁定,这会导致死锁.
您应该创建并使用自己的锁对象类.它可以使用关键部分或互斥锁来实现,具体取决于您是否要调试它.
创建自己的类有一个额外的好处:您可以实现锁定层次结构并在违反时引发异常.每次锁定不完全相同时,就会发生死锁.为每个锁分配锁定级别可以检查锁是否按正确的顺序进行.您可以将当前锁定级别存储在threadvar中,并且仅允许锁定具有较低锁定级别的锁定,否则会引发异常.这将捕获所有违规,即使没有发生死锁,所以它应该加快你的调试速度.
至于获取线程的堆栈跟踪,Stack Overflow上有很多问题可以解决这个问题.
更新
你写:
在这种情况下,我只处理一个关键部分和2个线程,所以这可能不是锁定排序问题.我相信有一个不正确的嵌套尝试跨越两个不同的线程进入锁定,这会导致死锁.
这不可能是整个故事.在Windows上无法单独使用两个线程和一个关键部分进行死锁,因为线程可以递归地获取关键部分.必须涉及另一种阻塞机制,例如SendMessage()
呼叫.
但是如果你真的只处理两个线程,那么其中一个必须是主/ VCL/GUI线程.在这种情况下,您应该能够使用MadExcept "主线程冻结检查"功能.它将尝试向主线程发送消息,并在经过可自定义的时间后失败而不处理消息.如果主线程在关键部分阻塞,而另一个线程在消息处理调用上阻塞,那么MadExcept应该能够捕获这个并为两个线程提供堆栈跟踪.
归档时间: |
|
查看次数: |
4043 次 |
最近记录: |