线程切换

线程切换的几种条件

如果学过操作系统,那么很容易就知道会有以下方法

  1. 时间片用完
  2. 强制切换
  3. 异常处理

时间片切换

其实也叫轮转调度算法,顾名思义当时间到达一定的时候,就会切换一个线程,接着运行,这样就可以让我们感受到我们的只有单核使用的程序却没有断过。

而在Windows中,当时间片到达时候,会引起中断异常也就是0x30

 Windows系列操作系统的时间片一般为:10-20毫秒

如果要获取当前的时钟间隔值,可以使用:GetSystemTimeAdjustment

时钟中断的执行流程

 主动切换

主要是KiSwapContext函数进行的

这里我在上一篇文章有逆向分析就不说了

线程切换TSS

在上一篇文章中,我们分析了KiSwapContext,所以我会直接说结论

线程切换的本质就是堆栈的切换,而新线程的堆栈存放_KTHREAD结构体中

 而且我们知道,在SwapContext函数里,esp会减少0x210,而这0x210存放的是浮点寄存器的值,其上面就是我们熟悉的_Trap_Frame结构了

 

 但是Windows和linux都没有使用这个东西,而是采用的堆栈来保存线程的各种寄存器的值

fs切换

由于fs在0环指向的是KPCR,3环指向的是TEB,所以FS也会切换,如何切换看我上一篇文章

优先级切换

上面我们提到有3种情况会导致线程切换:

 那么,上一篇文章我也有说KiFindReadThread是用来找到下一个要执行的线程的,那么是根据什么条件查找呢?

KiFindReadThread查找条件

由于有32个调度链表和1个空闲链表,KiFindReadyThread的查找方式是按照优先级来进行查找的:31...28....20..0

也就是有级别高的线程就直接指向级别高的了,就不会再去找级别低的了

如何让查找效率变高?

 如果没有就绪线程怎么办?

就会去空闲队列中查找

原文地址:https://www.cnblogs.com/pppyyyzzz/p/14268243.html