检测C#应用程序中的死锁

Jon*_*ury 22 c# multithreading deadlock

可能重复:
C#/ .NET分析工具,用于查找竞争条件/死锁

我正在调试一个应用程序,我怀疑它正在陷入僵局并挂起.但是,这只会每隔几天发生一次,并且它永远不会发生在我的计算机上,因此我无法将调试器挂钩.是否有任何实用程序或方法可以用来查询正在运行的应用程序,并找出哪些方法/锁定/它是什么死锁?

更新:通常,应用程序在客户位置运行,我无法访问该计算机,并且我不太愿意让他们安装大量软件.

Bri*_*sen 23

您可以使用WinDbg检查应用程序中的线程.以下是您可以做的简要计划.

  • 应用程序挂起时,将WinDbg文件复制到计算机.
  • 将WinDbg附加到进程或使用ADPlus获取进程的挂起转储.如果选择ADPlus,则在WinDbg中加载转储.
  • 从WinDbg加载sos.dll,以便检查托管代码.
  • !threads命令将显示应用程序和!clrstack命令中的所有线程,将显示它们正在执行的操作.使用~e!clrstack转储全部线程的调用堆栈.查找Wait方法的调用,因为它们表示锁定.
  • !syncblk命令将为您提供有关哪些线程持有不同锁的信息.
  • 要找出给定线程尝试获取的锁定,请切换到该线程并检查堆栈对象(!dso).从这里你应该能够找到线程试图获取的锁.

澄清:WinDbg不需要定期安装.只需复制文件.此外,如果您执行挂起转储,则可以根据需要继续在另一台计算机上进行调试.

增加:Sosex具有!dlk在许多情况下自动识别死锁的命令.它不会一直有效,但是当它发生时,它会为你完成所有的工作,所以这应该是你的第一选择.


Fre*_*els 8

您也可以使用"TimedLock"结构,而不是使用常规lockMonitor.Enter方法来锁定某些数据.如果无法及时获取锁定,则此TimedLock会抛出异常,如果您有一些未释放的锁定,它也会发出警告.

文章由Ian Griffiths的也许可以帮助.


naa*_*ing 6

并发编程中的超时是一个可怕的想法.这导致非确定性,从而导致无法再现的行为.尝试使用像CHESS这样的死锁检测工具.更好的是,最小化使用无锁算法的锁的数量,或完全避开锁并将程序划分为单线程隔离区并使用队列在隔离专区之间传递数据(更好地称为消息传递/ actor并发).