等待块(一)

_DISPATCHER_HEADER 结构

c 复制代码
//0x10 bytes (sizeof)
struct _DISPATCHER_HEADER
{
    union
    {
        struct
        {
            UCHAR Type;                                                     //0x0
            union
            {
                UCHAR TimerControlFlags;                                    //0x1
                struct
                {
                    UCHAR Absolute:1;                                       //0x1
                    UCHAR Coalescable:1;                                    //0x1
                    UCHAR KeepShifting:1;                                   //0x1
                    UCHAR EncodedTolerableDelay:5;                          //0x1
                };
                UCHAR Abandoned;                                            //0x1
                UCHAR Signalling;                                           //0x1
            };
            union
            {
                UCHAR ThreadControlFlags;                                   //0x2
                struct
                {
                    UCHAR CpuThrottled:1;                                   //0x2
                    UCHAR CycleProfiling:1;                                 //0x2
                    UCHAR CounterProfiling:1;                               //0x2
                    UCHAR Reserved:5;                                       //0x2
                };
                UCHAR Hand;                                                 //0x2
                UCHAR Size;                                                 //0x2
            };
            union
            {
                UCHAR TimerMiscFlags;                                       //0x3
                struct
                {
                    UCHAR Index:1;                                          //0x3
                    UCHAR Processor:5;                                      //0x3
                    UCHAR Inserted:1;                                       //0x3
                    volatile UCHAR Expired:1;                               //0x3
                };
                UCHAR DebugActive;                                          //0x3
                struct
                {
                    UCHAR ActiveDR7:1;                                      //0x3
                    UCHAR Instrumented:1;                                   //0x3
                    UCHAR Reserved2:4;                                      //0x3
                    UCHAR UmsScheduled:1;                                   //0x3
                    UCHAR UmsPrimary:1;                                     //0x3
                };
                UCHAR DpcActive;                                            //0x3
            };
        };
        volatile LONG Lock;                                                 //0x0
    };
    LONG SignalState;                                                       //0x4
    struct _LIST_ENTRY WaitListHead;                                        //0x8
}; 

在windows内核中,凡是头部以_DISPATCHER_HEADER 开始的对象都是被等待对象

如:

  • KTHREAD
  • KEVENT
  • KMUTANT(内核互斥体)
  • KSEMAPHORE
  • KTIMER
  • KQUEUE 等

_DISPATCHER_HEADER = 内核等待对象的公共头
Windows 等待机制里,线程是唯一的等待者;而带 _DISPATCHER_HEADER 的对象是可被等待的 dispatcher object,其中线程对象本身也属于可被等待对象。

等待者永远是线程;被等待者是 dispatcher object;线程对象本身既能等待别人,也能被别人等待。

KTHREAD._KWAIT_BLOCK

c 复制代码
//0x18 bytes (sizeof)
struct _KWAIT_BLOCK
{
    struct _LIST_ENTRY WaitListEntry;                                       //0x0
    struct _KTHREAD* Thread;                                                //0x8
    VOID* Object;                                                           //0xc
    struct _KWAIT_BLOCK* NextWaitBlock;                                     //0x10
    USHORT WaitKey;                                                         //0x14
    UCHAR WaitType;                                                         //0x16
    volatile UCHAR BlockState;                                              //0x17
}; 

线程一旦进入等待,内核就需要有个结构把这几个信息串起来:

  • 是谁在等(哪个线程)
  • 在等谁(哪个对象)
  • 这次等待属于哪种等待
  • 把它挂到哪个等待链表里

KWAIT_BLOCK 就是干这个的。它本质上是 线程 和 等待对象 之间的一条"挂接记录"。

字段解释

WaitListEntry

这是双向链表节点。

它的作用是把当前这个 KWAIT_BLOCK 挂到等待对象的 DISPATCHER_HEADER.WaitListHead 里。

也就是:"这个对象当前有哪些线程在等它",靠的就是这一串 KWAIT_BLOCK 链表。

Thread

指向正在等待的线程。

对象被置为 signaled 时,内核会通过这个字段知道:

应该唤醒哪一个线程。

Object

指向当前正在等待的对象。

这个对象通常就是某个 dispatcher object,比如:

  • event
  • semaphore
  • mutant / mutex
  • timer
  • thread

因为这些对象都带有 DISPATCHER_HEADER,所以都能维护等待链表。

NextWaitBlock

这是单向链表 把多个 KWAIT_BLOCK 串起来的指针。

它更偏向从线程这一侧去组织多个等待块。

当一个线程同时等待多个对象时,这些 KWAIT_BLOCK 可以通过 NextWaitBlock 组成链。

WaitKey

在 WaitAny / 多对象等待里,标识是第几个对象满足了等待。对应的值本质上就是该 KWAIT_BLOCK 在等待块数组里的 0 基索引。

WaitType

是枚举类型:

c 复制代码
typedef enum _WAIT_TYPE
{
	WaitAll,
	WaitAny
}WAIT_TYPE;
  • WaitAll:线程要等待所有对象都变成有信号状态
  • WaitAny:只要任意一个对象编程有信号状态即可。

BlockState

这是 等待块自身的状态。

它不是对象状态,也不是线程状态,而是这个 KWAIT_BLOCK 当前处于什么阶段。

相关推荐
x-cmd31 分钟前
[260429] x-cmd v0.9.1:一键开启 DeepSeek-V4-Pro Max 模式 + 1M 上下文;顺手重构了 uuid 模块
windows·重构·uuid·claude·curl·x-cmd·deepseek-v4-pro
今夕资源网1 小时前
Windows 上安装 Claude Code并且接入DeepSeekV4-Pro的Max模式和激活1M上下文
windows
HLJ洛神千羽2 小时前
电脑右下角显示【周几或星期几】和【上下午】方法
windows
ITHAOGE152 小时前
下载 | Windows Server 2025官方原版ISO映像!(4月更新、标准版、数据中心版、26100.32690)
服务器·windows·科技·微软·电脑
专注VB编程开发20年3 小时前
Windows API 所有老式结构体4字节对齐,但是64位VBA,Twinbasic弄成了8字节对齐,大BUG
windows·bug
东篱把酒黄昏4 小时前
wsl和Windows混合开发高级配置详细指导
windows
helloliyh5 小时前
windows设置定时任务开机执行bat或exe文件
windows
清水白石0085 小时前
从“类型体操”到工程设计:用 Python 解释协变、逆变与不变
网络·windows·python
卷Java6 小时前
上下文压缩
开发语言·windows·python
日取其半万世不竭6 小时前
Minecraft Java版社区服搭建教程(Windows版)
java·开发语言·windows