等待块(一)

_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 当前处于什么阶段。

相关推荐
洒满阳光的庄园3 小时前
Tauri Windows 桌面端:环境与构建流程
windows
love530love4 小时前
从零搭建本地版 Claurst:基于 Rust 重构的 Claude Code 终端编码助手 + LM Studio 模型接入测试
开发语言·人工智能·windows·重构·rust·lm studio·claude code
sunfdf4 小时前
在 Windows 11 上恢复已删除文件的 10 大方法 [2026]
windows
机智的爆爆哥4 小时前
Windows 下为 Claude 创建快捷命令
windows·ai·claude
十五年专注C++开发4 小时前
Linux 下用 VS Code 高效调试(二)
linux·c++·windows·vscode
取个名字太难了a4 小时前
WaitForSingleObject分析(二)
windows
雄哥0075 小时前
Windows系统下FFmpeg的安装与环境配置指南
windows·ffmpeg
charlie1145141915 小时前
通用GUI编程技术——图形渲染实战(二十六)——GDI+与GDI架构差异:抗锯齿与渐变
c++·windows·学习·图形渲染·win32
涔溪5 小时前
腾讯 WorkBuddy 超详细安装教程(Windows+macOS 全步骤)
windows·macos·workbuddy