Windows关键部分在什么情况下可能具有负锁定计数?

Wil*_*n F 8 c windows critical-section

是否有任何情况下Windows中的RTL_CRITICAL_SECTION结构的LockCount字段可以合法地为负数?

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

在此之前追逐之前,假设这是一件非常糟糕的事情,我只想验证这个假设是否正确.我几乎找不到有关RTL_CRITICAL_SECTION内部工作原理的信息.

Dav*_*nan 12

负锁定计数是某些Windows版本的正常行为.请注意,在Windows的生命周期中,此字段的含义已更改(请参阅下文).

解释这些私有字段是一件棘手的事情,您可以从使用专用的关键部分调试工具中受益.

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

一些相关的摘录:

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

......

在Microsoft Windows 2000和Windows XP中,LockCount字段指示任何线程为此关键部分调用EnterCriticalSection例程减去1的次数.对于未锁定的关键部分,此字段从-1开始.每次调用EnterCriticalSection都会递增此值; 每次调用LeaveCriticalSection都会减少它.例如,如果LockCount为5,则此关键部分被锁定,一个线程已获取它,另外五个线程正在等待此锁定.

......

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

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

然后继续解释如何解释锁定计数-22.总而言之,它比你想象的更棘手!


Ton*_*ion 5

这里,是一个部分解释:

LockCount这是关键部分中最重要的字段.它被初始化为-1的值; 值0或更大表示关键部分被保留或拥有.当它不等于-1时,OwningThread字段(此字段在WINNT.H中错误定义 - 它应该是DWORD而不是HANDLE)包含拥有此关键部分的线程ID.此字段与(RecursionCount -1)的值之间的差值表示有多少其他线程正在等待获取临界区.

  • "值为0或更大表示关键部分被保留或拥有"可能是真实的一次但在现代Windows上不再适用. (2认同)