8

是否存在 Windows 中 RTL_CRITICAL_SECTION 结构的 LockCount 字段可以合法为负的任何情况?

我们正在跟踪一个非常难以捉摸的崩溃,我们看到的一个症状是具有负 LockCount 的 CS。崩溃时,计数为 -6,但似乎通常为 -1、-2 等。

在假设发生这种情况是一件非常糟糕的事情之前,我只是想验证该假设是否正确。我几乎找不到关于 RTL_CRITICAL_SECTION 内部工​​作的信息。

4

2 回答 2

12

在某些 Windows 版本上,负锁计数是正常行为。请注意,此字段的含义在 Windows 的生命周期内发生了变化(见下文)。

解释这些私有字段是一项棘手的工作,您可能会从使用专用的关键部分调试工具中受益。

例如,请参阅此MSDN 文章提供了一些详细信息。特别是我认为它说明了为什么 -6 的值是完全合理的。

一些相关的摘录:

可以通过多种不同的方法在用户模式下显示关键部分。每个字段的确切含义取决于您使用的 Microsoft Windows 版本。

……

在 Microsoft Windows 2000 和 Windows XP 中,LockCount 字段表示任何线程为此临界区调用 EnterCriticalSection 例程的次数减一。对于未锁定的临界区,此字段从 -1 开始。每次调用 EnterCriticalSection 都会增加该值;每次调用 LeaveCriticalSection 都会递减它。例如,如果 LockCount 为 5,则此临界区已锁定,一个线程已获取它,另外五个线程正在等待此锁定。

……

在 Microsoft Windows Server 2003 Service Pack 1 及更高版本的 Windows 中,LockCount 字段解析如下:

  • 最低位显示锁定状态。如果该位为0,则临界区被锁定;如果为 1,则不锁定临界区。
  • 下一位显示是否已为此锁唤醒线程。如果该位为 0,则为该锁唤醒了一个线程;如果为 1,则没有线程被唤醒。
  • 其余位是等待锁的线程数的补码。

然后继续解释如何解释-22. 所以,总而言之,它比你想象的要棘手!

于 2011-09-13T21:31:45.277 回答
5

这里,是部分解释:

LockCount这是临界区中最重要的字段。它被初始化为值-1;值 0 或更大表示持有或拥有临界区。当它不等于 -1 时,OwningThread 字段(该字段在 WINNT.H 中的定义不正确——它应该是 DWORD 而不是 HANDLE)包含拥有该临界区的线程 ID。该字段与 (RecursionCount -1) 的值之间的差值表示有多少额外的线程正在等待获取临界区。

于 2011-09-13T21:32:06.680 回答