Windows处理器调度机制
一. 调度优先级
1. Windows处理器调度力度为线程,Windows为每一个线程分配调度优先级
2. 调度器根据优先级采用抢占式调度策略,让具有最高优先级的线程首先执行
3. Windows内核使用32个优先级分别来表示线程要求执行的紧迫性,用0~31的数字表示
4. 根据优先级的功能不同,可以分为3组:16个实时优先级别(16~31),15个可变优先级(1~15),1个系统优先级(0),为内存页清零线程保留
5. 当创建进程时,可以赋予一下优先级别:实时,高,高于一般,一般,低于一般和空闲
6. 当创建线程时,在进程的优先级别进一步赋予一下优先级别:尽量实时,最高,高于一般,一般,低于一般,最低和空闲
7. 应用优先级和系统的优先级别对应关系
36 |
15 |
12 |
10 |
8 |
6 |
35 |
14 |
11 |
9 |
7 |
5 |
24 |
13 |
10 |
8 |
6 |
4 |
23 |
12 |
9 |
7 |
5 |
3 |
22 |
11 |
8 |
6 |
4 |
2 |
实时 |
高 |
高于一般 |
一般 |
低于一般 |
空闲 |
8. 处理器调度时参考两个优先级设置:一个是从当前线程所在的进程的基准优先级,另外一个是线程的优先级
9. 一般来说,应该线程运行在可变优先级别(1~15)的范围内,如果需要进入实时优先级别(16~31)范围来运行,必须取得更高的调度优先级特权
二. 线程状态
1. 在处理器调度线程执行过程中,通过改变线程的状态对多个线程进行有效的管理
2. 如图2 一个线程在处理器调度过程中状态转化图
图2.Windows线程状态转化图
3. 如表2 线程状态的含义说明
状态 |
含义 |
就绪 |
表示一个线程已经准备就绪,等待运行。调度器查找线程库中处于就绪状态的线程,来决定下一个运行的线程 |
预备 |
表示一个线程已经被选择作为一个运行的线程,如果条件满足,调度器会将上下文环境切换到该线程。但处于预备状态的线程也可能会被转换到就绪状态继续等待 |
运行 |
当调度器将上下文环境切换到一个进程,该线程就处于运行状态。当分配给线程的时间配额用完,或则有更高优先级的线程抢占CPU,它会让出处理器 |
等待 |
当一个线程需要等待必要的系统资源时,会转入等待状态,知道系统资源就绪 |
过渡 |
如果一个线程已经准备就绪,但运行它所需的核心栈暂时被分页调度到磁盘上,它就进入过渡状态,等待核心栈调入内存 |
终止 |
当一个线程完成执行后,就进入终止状态,对象管理器释放相应的执行线程块资源 |
已初始化 |
一个线程刚被创建时的内部状态 |
三. 线程调度机制
1. Windows通过调度数据库来为每一个优先级别的线程维护一个就绪等待队列,当处理器需要调入一个线程运行时,系统会从调度数据库中找到一个具有最高优先级别的就绪线程,并分配执行时间
2. 系统中同时有多个线程存在,而每个处理器在一个时刻只能运行一个线程,Windows用调度数据记录处于就绪的线程,以便在确定一个执行的线程时参考
3. 当一个线程进入运行状态时,它获得一个可以运行的时间配额
4. 线程在核心线程块中都记录了当前的时间配额值,每过一个时钟周期,该值就会减1,当该值为0时,表示时间配额已经用完
5. 当分配给该线程的时间配额用完时,调度器会查找调度数据库看是否有就绪的线程在等待。如果有等待的就绪线程,调度器会将正在执行的线程转入等待或就绪队列,调入下一个具有最高优先级的线程执行。如果没有则再分配时间配额让该线程继续执行
6. Windows采用基于优先级的抢占式调度算法,在一个具有较低优先级别的线程正在运行时,如果有一个较高的优先级别的线程进入就绪等待队列,或一个具有较高优先级别的线程等待时间结束时,就可以抢占处理器优先执行
7. 当一个正在运行的线程需要等待某一个对象时,包括事件,互斥的状态解锁等,会主动让出处理器进入等待状态
8. 系统为每一个需要等待的对象维护了一个等待队列,让出处理器的线程会进入队尾等待,处在调度数据库中具有最高优先级的线程将被分配执行时间,并开始运行
9. 当一个线程的时间配额用完时,如果等待队列中有就绪线程等待,调度器会将当前线程移到就绪等待队列的队尾,而为具有最高优先级的线程分配运行时间,并开始运行
10. 当一个线程完成所有的代码运行,调度器会将它的状态设为结束。系统会将它从属进程的线程表中去掉,并释放它使用的内存和系统对象资源
11. 处理器调入和调出一个线程时,是通过切换上下文来实现的
12. 当系统调出一个正在运行的线程时,需要保存的线程上下文信息为运行指令指针,用户占和核心栈指针已经线程所在进程的虚拟地址空间指针
13. 线程的核心栈用来完成上下文的切换,调度器将调出线程的上下文环境信息压入该线程的核心栈,并将栈指针保存到该线程的核心线程块中
14. 在调入一个线程执行时,核心栈指针指向调入线程的核心栈,并恢复调入线的执行上下文
15. 如果调入线程所在的进程需要改变,处理器会将相关的地址寄存器设置到新进程的虚拟地址空间。处理器再将控制转到调入线的运行指令指针,开始运行该线程