c – 当它表示线程ID时,为什么CRITICAL_SECTION的OwningThread成员是HANDLE类型的?

前端之家收集整理的这篇文章主要介绍了c – 当它表示线程ID时,为什么CRITICAL_SECTION的OwningThread成员是HANDLE类型的?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试为CRITICAL_SECTION解锁代码添加一些调试检查,我尝试了以下方法
...
  if (m_pCritSect) {
    ASSERT(m_pCritSect->OwningThread == GetCurrentThreadId());
    LeaveCriticalSection(m_pCritSect);
  }
}

从调试CRITICAL_SECTIONS(使用VS 2005,主要是在WindowsXP上)我“知道”OwningThread(winnt.h中定义的RTL_CRITICAL_SECTION结构的成员)的值是持有锁的线程的ID的值.

但是,线程ID由DWORD(无符号长整数的typedef)值表示,而此变量的类型为HANDLE(typedef表示void *),需要reinterpret_cast才能使用basetsd.h中的HandleToULong宏来使上述代码生效.

即使是MSDN docs州:

When the first thread calls the EnterCriticalSection routine,(…)
OwningThread becomes the thread ID of the caller.

那么为什么在地球上这被定义为一个手柄呢?

编辑注意:我发现a statement,其中一张海报表明HANDLE / DWORD-Id不匹配是某些Windows内部的一些已知错误.所以也许这就是这种情况:

GetCurrentThreadId returns a DWORD,which I send up to the kernel in a
message. PsLookupThreadByThreadId takes the thread Id in a HANDLE,…

This is a known Windows API bug (“known” in that I talked to the
relevant filter manager DEV about this,as it shows up in Filter
Manager as well because of the I/O Manager API issue.) As long as you
don’t have more than a half billion or so threads and processes (they
use a single shared handle table) you’ll be fine. Maybe by the time
that’s a real issue,we’ll be running something different. [RE: ThreadId to HANDLE for 64 bit?,08 Aug 08 14:21,Tony Mason]

解决方法

名称以RTL或Rtl开头的SDK中的任何标识符都是运行时层的一部分的代码或声明,这是将记录良好的Winapi与未记录的本机操作系统api结合在一起的粘合剂. winapi是一成不变的,每个Windows版本的本机操作系统都会发生巨大变化.不可避免地,胶水也会发生变化.

winapi是记录层,本机操作系统没有记录.运行时层也没有记录,但随着时间的推移,部分内容被揭示出来.要么因为它回填了winapi中缺少的特征.或者,在这种情况下,因为解决问题真的很有用.然而,这样做的一个核心问题是,一旦宣布声明,微软就永远不会再改变它.因为这样做会破坏现有的程序,给客户带来很大的负担.

所以,ThreadOwner字段曾经真正拥有以前Windows版本中线程的句柄.注意LockSemaphore是如何误导的,它实际上是一个自动重置事件.修理它太晚了,这只猫已经不在了.

猜你在找的C&C++相关文章