线程锁无限等待
本文关键字:等待 无限 线程 | 更新日期: 2023-09-27 18:06:55
面临间歇性多线程错误,显示为应用程序挂起。当我暂停调试时,我看到线程等待lock(_sync)子句。问题是:
- 当其他线程锁定对象时,这是等待锁定的唯一原因吗?
- 如何知道哪个线程持有特定对象的锁(在调试或运行时)?
我认为它不是"死锁",因为死锁意味着至少存在两个对象和两个线程,而在考虑代码时只有一个同步对象。我认为其他线程锁定了对象并挂起,但我找不到它是哪个线程
我将记录一些基本的调试技术。从Debug + Windows + Threads开始,它会显示进程中正在运行的所有线程的列表。您可以将鼠标悬停在Location列上,您将获得一个工具提示,显示线程的堆栈跟踪。这样可以让您快速回到实际运行代码的线程上。双击感兴趣的一个,然后切换到Debug + Windows + Call Stack以获得更永久的视图。这可以帮助您找到已经获得锁的线程。
如果不这样做,您可以找出哪个线程拥有锁对象。切换到被阻塞的线程,双击它,然后使用调试+ Windows +内存+内存1。在地址栏中输入"_sync"。右键单击窗口,选择"4字节整数"。从窗口左上角显示的十六进制地址减去4,然后在"地址"框中键入该地址。或者单击向上滚动条箭头并查看第一行中的最后一个值。这就是那条线。拥有锁的线程的ManagedThreadId。注意,这并不总是有效的,对象中的这个字段也被用于其他目的(例如GetHashCode)。
知道线程的托管ID现在可以让您在Debug + Windows + Threads窗口中查看线程。但只有在VS2010上,早期版本不会在此窗口中显示线程的托管ID。对于这些,您需要添加一些跟踪代码来显示Thread.CurrentThread.ManagedThreadId的值。添加跟踪代码通常是解决线程问题的一种有用技术。这是非常危险的,然而,这段代码改变了计时,并可能使线程问题消失。许多跟踪侦听器也有一个隐含锁。
调试这个的一种方法(没有漂亮闪亮的VS2010功能)是使访问_sync只可能使用属性/访问器。这里放了一些诊断文本或断点,你可以看到哪个线程想要同步以及何时同步。
在没有看到代码的情况下,我无法给出任何合理的答案