Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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#_Multithreading_Deadlock - Fatal编程技术网

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

检测C#应用程序中的死锁,c#,multithreading,deadlock,C#,Multithreading,Deadlock,可能重复: 我正在调试一个应用程序,我怀疑它正陷入僵局并挂起。然而,这只会每隔几天发生一次,而且在我的计算机上从未发生过,所以我无法将调试器连接到它。我是否可以使用任何实用程序或方法来查询正在运行的应用程序,并找出哪些方法/锁/什么是死锁的 更新:通常应用程序在客户位置运行,而我无权访问机器,我不太愿意让他们安装成吨的软件。的结尾说,在Vista上,至少可以使用任务管理器对正在运行的进程进行崩溃转储。这是一个非常有趣的问题,也是一个痛苦的问题,因为它只会每隔几天发生一次。我找到了。这可能是你的

可能重复:

我正在调试一个应用程序,我怀疑它正陷入僵局并挂起。然而,这只会每隔几天发生一次,而且在我的计算机上从未发生过,所以我无法将调试器连接到它。我是否可以使用任何实用程序或方法来查询正在运行的应用程序,并找出哪些方法/锁/什么是死锁的


更新:通常应用程序在客户位置运行,而我无权访问机器,我不太愿意让他们安装成吨的软件。

的结尾说,在Vista上,至少可以使用任务管理器对正在运行的进程进行崩溃转储。

这是一个非常有趣的问题,也是一个痛苦的问题,因为它只会每隔几天发生一次。我找到了。这可能是你的一个开始


一种老派的方法是记录大量消息,并使用日志文件尝试检测消息何时发生。:)

你实际上有一个非常有趣的问题。您可以做以下几件事:

使用一个好的记录器:重现多线程错误的方法之一是使用一个记录器,它将打印所采取的操作和执行这些操作的线程,这样您就可以找到一个跟踪,从而引导您找到错误。如果可以添加记录器,这是一个相当简单的解决方案

使用FSP:使用FSP定义多线程系统。通过这种方式,您将能够创建一个进程的有限状态机,您可以通过它来查找错误。这个解是一个更数学的解

我给你们的两个解决方案/程序正是一些英国大学和美国大学在多线程开发方面的主要区别。在英国,教授们更喜欢尝试和证明他们的系统在使用程序之前没有使用FSP的错误,美国人更喜欢测试证明他们工作正常,这是一个味觉的问题。 我真的建议您阅读这本书:Jeff Magee和Jeff Kramer:并发性:状态模型和Java程序,Wiley,1999

您可以用来检查应用程序中的线程。这里有一个你可以做的简单计划

  • 应用程序挂起时,将WinDbg文件复制到计算机上
  • 将WinDbg连接到进程或使用ADPlus获取进程的挂起转储。如果选择ADPlus,则在WinDbg中加载转储
  • 从WinDbg加载sos.dll,以便检查托管代码
  • !threads
    命令将显示应用程序和
    中的所有线程!clrstack
    命令,将显示它们正在执行的操作。使用
    ~e!clrstack
    转储所有线程的调用堆栈。查找对Wait方法的调用,因为它们指示锁定
  • !syncblk
    命令将为您提供哪些线程持有不同锁的信息
  • 要找出给定线程试图获取的锁,请切换到该线程并检查堆栈对象(
    !dso
    )。从这里您应该能够找到线程试图获取的锁
澄清:WinDbg不需要定期安装。只需复制文件。此外,如果您接受挂起转储,您可以根据需要在另一台机器上继续调试


添加:具有
!dlk
命令,可在许多情况下自动识别死锁。它并不总是有效,但当它有效时,它会为你做所有的工作,所以这应该是你的第一选择

不使用常规的
锁定
&
监视器。输入
方法锁定某些数据,也可以使用“TimedLock”结构。 如果无法及时获取锁,此TimedLock会引发异常,如果您有一些未释放的锁,它还会向您发出警告


Ian Griffiths的文章可能会有所帮助。

除了这里的答案之外,你会发现线程编程的另一个有用之处是确保你的开发环境是一台多处理器机器,死锁尤其是(通常)死锁更可靠地复制。并发编程中的超时是一个可怕的想法。这会导致非决定论,从而导致无法复制的行为。尝试使用死锁检测工具,如。更好的方法是,尽量减少无锁算法使用的锁的数量,或者完全避免锁,将程序划分为单线程分区,并使用队列在分区之间传递数据(更好地称为消息传递/参与者并发)。

我将首先尝试一下,并添加一系列日志记录,以尝试跟踪失败的锁。谢谢正如本文所示,TimedLock存在潜在问题:您有源代码吗!dlk命令也值得一提。。。它只是为您找到死锁的线程。@icareo说得好。但是,在某些情况下,它不起作用,因此最好知道如何手动完成此操作。在Windows 10上也可以使用。