等待块(一)

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

相关推荐
seahahacsdn29 分钟前
Windows获取SYSTEM用户权限的方法应用-计划任务
windows
上海云盾-小余1 小时前
七层 CC 攻击检测难点:如何区分真实用户与攻击请求
网络·人工智能·windows·tcp/ip·udp
2501_915106321 小时前
Windows 上开发 Unity iOS,使用 KXBuild 进行真机调试、性能采样与打包 ipa
windows·vscode·unity·ios·个人开发·swift·敏捷流程
西柚不烦恼2 小时前
Windows 本地部署私有 AI 全攻略:纯 CPU 环境(Ollama + Open WebUI)
人工智能·windows
少年的范儿2 小时前
Windows 安装 Node.js 教程:nvm 版本管理 + pnpm 安装配置
windows·npm·node.js
bu_shuo5 小时前
删除Windows资源管理器左侧【此电脑】的Linux企鹅图标
linux·windows
清水白石0085 小时前
Python 安装与环境配置:Windows、macOS、Linux 完整指南(第2集)
windows·python·macos
木卫二号Coding6 小时前
关闭-Windows10文件资源管理器-预览窗格-有效
windows
Moshow郑锴6 小时前
GCP MIG 重建后 Ansible 初始化实战:PowerShell + NSSM 挂载 Windows 服务
windows·ansible
染指11106 小时前
160.Agent-LangGraph-自定义主管架构智能体
人工智能·windows·microsoft·langchain·1024程序员节·agents