线程锁无限等待

时间:2011-08-28 09:17:21

标签: c# .net multithreading

面对应用程序挂起时出现的间歇性多线程错误。当我暂停调试时,我看到该线程等待锁(_sync)子句。所以问题是:

  1. 是否有其他线程锁定对象时等待锁定的唯一原因?
  2. 如何知道持有特定对象锁的线程(在调试或运行时)?
  3. 我认为它不是“死锁”,因为死锁意味着存在至少两个对象和两个线程,而在考虑代码时只有一个同步对象。我认为其他一些线程锁定了对象并挂了但我无法找到它所在的线程。

2 个答案:

答案 0 :(得分:4)

我将记录一些基本的调试技巧。从Debug + Windows + Threads开始,它显示了进程中正在运行的所有线程的列表。您可以将鼠标悬停在“位置”列上,您将获得一个工具提示,显示该线程的堆栈跟踪。这使您可以快速回到实际运行代码的线程。双击感兴趣的一个,然后切换到Debug + Windows + Call Stack以获得更永久的视图。这可以帮助您找到已获得锁定的线程。

如果失败了,你可以找出拥有锁对象的线程。通过双击切换到被阻止的线程,然后使用Debug + Windows + Memory + Memory 1.在地址框中键入“_sync”。右键单击窗口并选择“4字节整数”。从窗口左上角显示的十六进制地址中减去4,然后在地址框中键入该地址。或者单击向上滚动条箭头并查看第一行中的最后一个值。这是拥有锁的线程的Thread.ManagedThreadId。请注意,这并不总是有效,对象中的此字段也用于其他目的(例如GetHashCode)。

现在知道线程的托管ID,可以在Debug + Windows + Threads窗口中查找该线程。但仅在VS2010上,早期版本不会在此窗口中显示线程的托管ID。对于那些,您需要添加一些显示Thread.CurrentThread.ManagedThreadId值的跟踪代码。添加跟踪代码通常是解决线程问题的有用技术。然而,这是非常危险的,这段代码改变了时间并可能使线程问题消失。许多跟踪侦听器也有隐含的锁。

答案 1 :(得分:0)

调试此方法的一种方法(没有漂亮闪亮的VS2010)将只能通过属性/访问器访问_sync。有一些诊断文本或断点,你可以看到什么线程想要同步和什么时候。

除此之外,如果没有看到代码,我就无法给出任何合理的答案。