typedef struct _KTHREAD {
//
// The dispatcher header and mutant listhead are fairly infrequently
// referenced.
//
DISPATCHER_HEADER Header; // KTHREAD 是可等待对象,线程结束时有信号
// 此链表存储了属于该线程的所有 mutant(对应3环的 mutex)
// 一旦该线程获得了 mutex ,则 mutex 挂入该链表
LIST_ENTRY MutantListHead;
//
// The following fields are referenced during context switches and wait
// operatings. They have been carefully laid out to get the best cache
// hit ratios.
// 下面的域布局精心设计以提高 cache 命中率
PVOID InitialStack; // 原始栈底
PVOID StackLimit; // 栈顶的最低地址(栈界限)
PVOID KernelStack; // 内核栈顶esp,线程切换时保存esp到这里
// 自旋锁对象,用于保护线程数据成员
KSPIN_LOCK ThreadLock;
// KAPC_STATE 存储了该线程的APC信息,包括用户/内核APC链表,当前所属进程(父进程或挂靠进程)
// 是否正在执行内核APC,是否有要执行的用户/内核APC
union {
KAPC_STATE ApcState;
struct {
// 用来占用一个 KAPC_STATE 的大小
UCHAR ApcStateFill[KAPC_STATE_ACTUAL_LENGTH];
BOOLEAN ApcQueueable; // 是否可以插入APC
volatile UCHAR NextProcessor; // 处理器调度相关
volatile UCHAR DeferredProcessor; // 处理器调度相关
UCHAR AdjustReason; // 优先级调整的原因
SCHAR AdjustIncrement; // 优先级调整量
};
};
// 自旋锁对象,用于保护APC队列操作
KSPIN_LOCK ApcQueueLock;
#if !defined(_AMD64_)
ULONG ContextSwitches; // 记录线程切换次数
volatile UCHAR State; // 9种线程状态,见 _KTHREAD_STATE ,1就绪,2运行,5等待
UCHAR NpxState; // 浮点寄存器状态,本书不讨论
KIRQL WaitIrql; // 配合 WaitNext 使用,详见 WaitNext 注释
KPROCESSOR_MODE WaitMode; // 线程等待时的处理器模式,0内核,1用户
#endif
LONG_PTR WaitStatus; // 等待的结果状态
union {
// 指向一个以 KWAIT_BLOCK 为元素的链表
// KWAIT_BLOCK 对象指明了哪个线程在等待哪个分发器对象
// 对于分发器对象,它又有另一个 KWAIT_BLOCK 链表指明哪些线程正在等待它
// 细节要等到 5.4 节介绍线程同步机制时才能知道
PKWAIT_BLOCK WaitBlockList;
// 记录了正在等待的门对象(也是一种分发器对象)
PKGATE GateObject;
// 等待门对象和等待其他分发器对象不会同时发生,所以放在一个共用体里了
};
BOOLEAN Alertable; // 线程等待时,是否可以被唤醒
// WaitNext == TRUE 表示这个线程马上要调用一个内核等待函数,所以不必解除线程调度器锁
// WaitNext == TRUE 时,WaitIrql 记录了原先的 IRQL 值。
BOOLEAN WaitNext;
// 记录线程等待的原因,见 KWAIT_REASON 枚举类型,但不参与线程调度或决策
UCHAR WaitReason;
SCHAR Priority;
KTHREAD 结构体属性介绍
最新推荐文章于 2024-11-01 10:48:03 发布