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

发布于 2024-12-04 05:08:55 字数 240 浏览 0 评论 0原文

Windows 中 RTL_CRITICAL_SECTION 结构的 LockCount 字段是否可以合法为负数?

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

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

Is there any circumstance in which the LockCount field of a RTL_CRITICAL_SECTION structure in Windows can legitimately be negative?

We're tracking a VERY elusive crash and one symptom we're seeing is a CS with a negative LockCount. At the time of the crash, the count is -6, but it seems to routinely be -1, -2, etc.

Before go chasing off after that on the assumption that it is a Very Bad Thing for this to occur, I just want to verify that that assumption is correct. I can find little to no information on the inner workings of RTL_CRITICAL_SECTION.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

李白 2024-12-11 05:08:55

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

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

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

一些相关摘录:

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

……

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

……

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

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

然后继续解释如何解释 -22 的锁定计数。因此,总而言之,这比您想象的要棘手!

Negative lock count is normal behaviour on some Windows versions. Note that the meaning of this field has changed during the lifetime of Windows (see below).

Interpreting these private fields is a tricky business and you may benefit from using dedicated critical section debugging tools.

For example, see this MSDN article gives some details. In particular I think it shows why a value of -6 is perfectly plausible.

Some pertinent excerpts:

Critical sections can be displayed in user mode by a variety of different methods. The exact meaning of each field depends on the version of Microsoft Windows version you are using.

......

In Microsoft Windows 2000, and Windows XP, the LockCount field indicates the number of times that any thread has called the EnterCriticalSection routine for this critical section, minus one. This field starts at -1 for an unlocked critical section. Each call of EnterCriticalSection increments this value; each call of LeaveCriticalSection decrements it. For example, if LockCount is 5, this critical section is locked, one thread has acquired it, and five additional threads are waiting for this lock.

......

In Microsoft Windows Server 2003 Service Pack 1 and later versions of
Windows, the LockCount field is parsed as follows:

  • The lowest bit shows the lock status. If this bit is 0, the critical
    section is locked; if it is 1, the critical section is not locked.
  • The next bit shows whether a thread has been woken for this lock. If
    this bit is 0, then a thread has been woken for this lock; if it is 1,
    no thread has been woken.
  • The remaining bits are the ones-complement of the number of threads
    waiting for the lock.

It then goes on to explain how to interpret a lock count of -22. So, in summary, it's trickier than you might think!

梦途 2024-12-11 05:08:55

此处是部分说明:

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

From here, is a part explanation:

LockCount This is the most important field in a critical section.
It is initialized to a value of -1; a value of 0 or greater indicates
that the critical section is held or owned. When it's not equal to -1,
the OwningThread field (this field is incorrectly defined in
WINNT.H—it should be a DWORD instead of a HANDLE) contains the thread
ID that owns this critical section. The delta between this field and
the value of (RecursionCount -1) indicates how many additional threads
are waiting to acquire the critical section.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文