2.1调度的基本概念
CPU调度是对CPU进行分配,即从就绪队列中按照一定的算法(公平、高效的原则)选择一个进程并将CPU分配给它运行,以实现进程并发地执行。
CPU调度是多道程序操作系统的基础,是操作系统设计的核心问题。
2.2调度的分类(三级调度)
一个作业从提交到完成,需要经历一下三级调度
- 作业调度为进程活动做准备,进程调度使进程正常活动起来。
- 中级调度将暂时不能运行的进程挂起,中级调度处于作业调度和进程调度之间
- 作业调度次数少,中级调度次数略多,进程调度频率最高。
- 进程调度是最基本的,不可或缺。
2.3调度的实现
2.3.1调度程序/调度器/scheduler
用于调度和分派CPU的组件称为调度程序
排队器:将系统中的所有就绪进程按照一定的策略排成一个或多个队列,以便于调度程序选择。每当有一个进程转变为就绪态时,排队器便将它插入相应的就绪队列
分派器:依据调度程序所选的进程,将其从就绪队列中取出,将CPU分配给新进程
上下文切换器:在对CPU进行切换时,会发生两对上下文的切换操作:第一对,当前进程将自己的上下文保存到其PCB中,再装入分派程序的上下文,以便分派程序运行;第二对,移出分派程序的上下文,将新选进程的CPU现场信息装入CPU的各个相应寄存器;现在己有硬件实现的方法来减少上下文切换时间。通常采用两组寄存器,其中一组供内核使用,一组供用户使用。这样,上下文切换时,只需改变指针,让其指向当前寄存器组即可
2.3.2调度的时机
- 创建新进程后,由于父进程和子进程都处于就绪态,因此需要决定是运行父进程还是运行子进程,调度程序可以合法地决定其中一个进程先运行。
- 进程正常结束后或者异常终止后,必须从就绪队列中选择某个进程运行。若没有就绪进程,则通常运行一个系统提供的闲逛进程。
- 当进程因I/O请求、信号量操作或其他原因而被阻塞时,必须调度其他进程运行。
- 当I/O设备完成后,发出I/O中断,原先等待I/O的进程从阻塞态变为就绪态,此时需要决定是让新的就绪进程投入运行,还是让中断发生时运行的进程继续执行。
- 当有更紧急的任务(如更高优先级的进程进入就绪队列)需要处理时,或者当前进程的时间片用完时,也被强行剥夺CPU(被动放弃)
不能进行进程调度与切换的情况
- 在处理中断的过程中。中断处理过程复杂,在实现上很难做到进程切换,而且中断处理是系统工作的一部分,逻辑上不属于某一进程,不应被剥夺CPU资源。
- 需要完全屏蔽中断的原子操作过程中。如加锁、解锁、中断现场保护、恢复等原子操作。
2.3.3进程调度的方式
非抢占调度方式(非剥夺方式)
是指当一个进程正在CPU上执行时,即使有某个更为重要或紧迫的进程进入就绪队列,仍然让正在执行的进程继续执行;非抢占调度方式的优点是实现简单,系统开销小,适用于早期的批处理系统
抢占调度方式(剥夺方式)
是指当一个进程正在CPU上执行时,若有某个更为重要或紧迫的进程需要使用CPU,则允许调度程序根据某种原则去暂停正在执行的进程,将 CPU分配给这个更为重要或紧迫的进程;抢占调度方式对提高系统吞吐率和响应效率都有明显的好处
2.3.4闲逛进程
在进程切换时,如果系统中没有就绪进程,就会调度闲逛进程(Idle Process)运行,它的PID为0。如果没有其他进程就绪,该进程就一直运行,并在指令周期后测试中断。闲逛进程的优先级最低,没有就绪进程时才会运行闲逛进程,只要有进程就绪,就会立即让出CPU.
闲逛进程不需要CPU之外的资源,它不会被阻塞
2.4进程(上下文)的切换
切换CPU到另一个进程需要保存当前进程状态并恢复另一个进程的状态,这个任务称为上下文切换。上下文切换通常是计算密集型的,在每秒几十上百次的切换中,每次切换都需要纳秒量级的时间,所以上下文切换对系统来说意味着消耗大量的CPU时间。进程上下文采用进程PCB表示,包括CPU寄存器的值、进程状态和内存管理信息等。当进行上下文切换时,内核将旧进程状态保存在其PCB中,然后加载经调度而要执行的新进程的上下文。在切换过程中,进程的运行环境产生实质性的变化。上下文切换的流程如下:
- 挂起一个进程,将CPU上下文保存到PCB,包括程序计数器和其他寄存器。
- 将进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列。
- 选择另一个进程执行,并更新其PCB.
- 恢复新进程的CPU上下文。
- 跳转到新进程PCB中的程序计数器所指向的位置执行