Windows内核-线程

以下针对WindowsXP
线程三种状态:运行、等待、就绪。
(1)处于运行态的线程存储在KPCR中
(2)处于就绪态和等待态的线程处于另外33个链表中,其中1个是等待链表,32个是就绪链表。(Win7、WIn10 64个)。这些链表使用_KTHREAD(+0x60)追踪线程,即线程在某一时刻,只能属于其中一个圈。(不管是就绪态还是等待态都挂在_KTHREAD(+0x60),即在_KTHREAD中用一块地址,指向等待链表和就绪链表

等待链表/调度链表

(1)若线程调用了Sleep()或者WaitForSingleObject()等函数,线程就挂到等待链表中,处于挂起态。
(2)32个调度链表,每个链表优先级不同
windbg使用如下命令查看等待链表头:

dd KiWaitListHead

windbg使用如下命令查看调度链表(32个):

dd KiDispatcherReadyListHead L50

在这里插入图片描述

线程切换

每个线程有自己的内核堆栈,线程内核堆栈如下:
在这里插入图片描述
每个内核堆栈具体如下:InitialStack开始的0x210字节存储浮点寄存器的时,从0x210开始到KernelStack存储_Trap_Frame结构。
在这里插入图片描述

线程切换有三种方式(1)主动切换(2)时钟中断(3)异常

主动切换

执行流程:API函数---->KiSwapThread---->KiSwapContext---->SwapContext

线程调用SwapContext内核函数进行线程切换。
         (1)Windows中大部分API调用SwapContext函数,该函数用于线程切换(内部是将下一个线程的栈顶指向KPCR中的当前线程的栈顶)
         (2)线程切换时会边角是否属于同一个进程,若不是则切换Cr3.

时钟中断

具备以下两个条件通过调用SwapContext()内核函数切换线程:
         (1)当前CPU时间片到期
         执行流程:KiDispatchInterrupt---->KiQuantumEnd---->SwapContext
         (2)有备用线程(即KPCR.PrcbData.NextThread存在)
         执行流程:KiDispatchInterrupt---->SwapContext

CPU时间片
         (1)一个新的线程开始时,线程初始化程序会为_KTHREAD.Quantum赋初始值,该值的大小由_KPROCESS.ThreadQuantum决定。
         (2)每次时钟中断调用KeUpdateRuntime函数,该函数每次将当前线程Quantum减少3个单位(例如若Quantum=6,需要2个时钟中断才可以让CPU时间片到期),若Quantum=0,则将KPCR.PrcbData.QuantumEnd设为非0(代表该线程时间片到期)
         (3)函数KiDispatchInterrup判断时间片到期,调用KiQuantumEnd重新设置时间片,在KiQuantumEnd中通过KiFindReadyThread找到下一个线程,进行线程切换。当前线程被挂到调度链表

备用线程
若当前CPU时间片没到期,但是当前线程有备用线程,即KPCR.PrcbData.NextThread存在,线程也会发生切换。

异常处理

也是通过调用SwapContext()内核函数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值