Windows时间片管理
2023-11-14
13
0
关于时间片
1) 当一个新的线程开始执行时,初始化程序会在KTHREAD.Quantum赋初始值,该值的大小由KPROCESS.ThreadQuantum
决定(观察ThreadQuantum大小)
2) 每次时钟中断会调用KeUpdateRunTime函数,该函数每次将当前线程Quantum减少3个单位,如果减到0,则将KPCR.PrcbData.QuantumEnd的值设置为非0。
3) KiDispatchInterrupt判断时间片到期:调用KiQuantumEnd(重新设置时间片、找到要运行的线程)
PROCESS ffffd5071853d580
SessionId: 1 Cid: 1d54 Peb: 5ea845d000 ParentCid: 0f34
DirBase: 13d80002 ObjectTable: 00000000 HandleCount: 0.
Image: conhost.exe
3: kd> dt _KPROCESS ffffd5071853d580
nt!_KPROCESS
+0x000 Header : _DISPATCHER_HEADER
+0x018 ProfileListHead : _LIST_ENTRY [ 0xffffd507`1853d598 - 0xffffd507`1853d598 ]
+0x028 DirectoryTableBase : 0x13d80002
+0x030 ThreadListHead : _LIST_ENTRY [ 0xffffd507`1853d5b0 - 0xffffd507`1853d5b0 ]
+0x040 ProcessLock : 0
+0x044 Spare0 : 0
+0x048 DeepFreezeStartTime : 0
+0x050 Affinity : _KAFFINITY_EX
+0x0f8 ReadyListHead : _LIST_ENTRY [ 0xffffd507`1853d678 - 0xffffd507`1853d678 ]
+0x108 SwapListEntry : _SINGLE_LIST_ENTRY
+0x110 ActiveProcessors : _KAFFINITY_EX
+0x1b8 AutoAlignment : 0y0
+0x1b8 DisableBoost : 0y0
+0x1b8 DisableQuantum : 0y0
+0x1b8 DeepFreeze : 0y0
+0x1b8 TimerVirtualization : 0y0
+0x1b8 CheckStackExtents : 0y1
+0x1b8 SpareFlags0 : 0y00
+0x1b8 ActiveGroupsMask : 0y00000000000000000001 (0x1)
+0x1b8 ReservedFlags : 0y0000
+0x1b8 ProcessFlags : 0n288
+0x1bc BasePriority : 8 ''
+0x1bd QuantumReset : 18 ''
+0x1be Visited : 0 ''
+0x1bf Flags : _KEXECUTE_OPTIONS
+0x1c0 ThreadSeed : [20] 0
+0x210 IdealNode : [20] 0
+0x238 IdealGlobalNode : 0
+0x23a Spare1 : 0
+0x23c StackCount : _KSTACK_COUNT
+0x240 ProcessListEntry : _LIST_ENTRY [ 0xfffff802`4b197120 - 0xffffd507`187ea2c0 ]
+0x250 CycleTime : 0x194ab0b6
+0x258 ContextSwitches : 0x55c
+0x260 SchedulingGroup : (null)
+0x268 FreezeCount : 0
+0x26c KernelTime : 5
+0x270 UserTime : 3
+0x274 Spare2 : [75] ""
+0x2bf AddressPolicy : 0 ''
+0x2c0 UserDirectoryTableBase : 0x00000002`3b700001
+0x2c8 InstrumentationCallback : (null)
+0x2d0 SecurePid : 0
存在备用线程
这个值被设置时,即使当前线程的CPU时间片没有到期,仍然会被切换.
参见KiDispatchInterrupt代码
线程切换的3种情况
(1)、当前线程主动调用API:
API函数 -> KiSwapThread -> KiSwapContext -> SwapContext
(2)、当前线程时间片到期:
KiDispatchInterrupt -> KiQuantumEnd -> SwapContext
(3)、有备用线程(KPCR.PrcbData.NextThread)
KiDispatchInterrupt -> SwapContext