如何找到锁(监视器)的所有者?

10

有没有一种方法可以发现当前拥有锁的线程? 具体来说,我正在寻找一些代码以打印阻止锁被获取的线程。我想尝试在给定的超时时间内进行锁定,然后报告哪个线程阻止了锁的获取。


为什么要特别针对C#?在Java的情况下可能会有同样的疑问。 - Saurabh Gokhale
1
@掩盖 这个问题可能存在于所有/大多数具有线程和锁定功能的运行时/语言中,但他特别要求提供代码。 - Lasse V. Karlsen
2个回答

8

不需要解释,只需编写代码:

private int lockOwner;
private object lockObject = new object();
...
void foo() {
    lock(lockObject) {
        lockOwner = Thread.CurrentThread.ManagedThreadId;
        // etc..
    }
}

有一种未被记录的方法可以获取锁的拥有者,虽然不能保证一定成功,但通常都可以。当您有一个断点处于活动状态时,请使用“调试(Debug) + 窗口(Windows) + 内存(Memory) + 内存1(Memory1)”选项卡。在地址输入框中,键入锁定对象的名称("lockObject"),然后按Enter键。地址框会更改为内存中对象的地址。编辑并在地址末尾添加 "-4",然后按Enter键。转储中的前4个字节以十六进制形式给出了受管线程ID。这对32位代码有效,只要您从未在锁定对象上调用过GetHashCode()函数,当然您不应该这样做。


你可能想要修正 lockObject 的类型。 - Lasse V. Karlsen
你能解释一下为什么不应该在用于锁定的对象上调用GetHashCode()方法吗?你是说一般情况下都不应该这样做,还是只针对这个内存查看的目的? - crokusek

0

编辑:

C#:

对于C#,您可以在这里找到答案:

来自Hans Passant的建议:

class Test {
    private object locker = new object();
    public void Run() {
        lock (locker) {  // <== breakpoint here
            Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
        }
    }
}

java.util.concurrent 如何帮助 C#? - Lasse V. Karlsen
@Lasse:问题不应该只限于C#。在Java中也可能存在同样的疑问。我的回答与Java有关。 - Saurabh Gokhale
2
很抱歉,但如果他需要针对.NET程序的答案,那么他完全有权提出关于.NET和C#的问题。如果您想要Java程序的答案,您需要自己提问。我拒绝了您建议添加Java标签的编辑。这是一个.NET问题,该问题可能存在于Java和许多其他运行时/语言中,但如果您想要一个通用答案,请提出自己的问题,不要试图将此问题变成它不是的东西。 - Lasse V. Karlsen
既然他要求代码,了解Java或Objective-C或其他语言的代码对他没有任何帮助。我还假设(但我当然可能错了),获取该信息所涉及的技术细节取决于运行时、语言、操作系统等等,因此通用的答案可能不存在。 - Lasse V. Karlsen
1
@Lasse:没问题。现在,我也回答了关于C#的问题。这样怎么样? - Saurabh Gokhale
@所有人:对不起,我没有看到Hans Passant已经回答了这个问题。我只是提供了他在另一个问题中已经给出的答案链接。 - Saurabh Gokhale

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接