2.2.1 调度的概念
1. 调度的基本概念
对处理机进行分配,即从就绪队伍中按照一定的算法选择一 个进程并将处理机分配给它运行
2. 调度的层次
1) 高级调度(作业调度)
作业调度就是内存与辅存之间的调度。每个作业只调入一次、调出一次。
高级调度过程
按照一定的原则从外存上处于后备队列的作业中挑选一个(或多个),给它(们)分配内存、输入/输出设备等必要的资源,并建立相应的进程,以使它(们)获得竞争处理机的权利。
2) 中级调度(内存调度)
中级调度实际上是存储器管理中的对换功能。引入中级调度的目的是提高内存利用率和系统吞吐量。
中级调度过程
- 将那些暂时不能运行的进程调至外存等待,此时进程的状态称为挂起态。
- 当它们已具备运行条件且内存又稍有空闲时,由中级调度来决定把外存上的那些已具备运行条件的就绪进程再重新调入内存,并修改其状态为就绪态,挂在就绪队列上等待。
3) 低级调度(进程调度)
按照某种算法从就绪队列中选取个进程,将处理机分配给它。
进程调度是最基本的一种调度,在各种操作系统中都必须配置这级调度。
3. 三级调度的联系
作业调度从外存的后备队列中选择一批作业进入内存,为它们建立进程,这些进程被送入就绪队列,进程调度从就绪队列中选出一个进程,并把其状态改为运行态,把CPU分配给它。
- 作业调度为进程活动做准备,进程调度使进程正常活动起来。
- 中级调度将暂时不能运行的进程挂起,中级调度处于作业调度和进程调度之间。
- 作业调度次数少,中级调度次数略多,进程调度频率 最高。
- 进程调度是最基本的,不可或缺。
2.2.2 调度的目标
- CPU利用率。CPU是计算机系统中最重要和昂贵的资源之一,所以应尽可能使CPU保持“忙”状态,使这一资源利用率最高。CPU 利用率的计算方法如下:
C P U 的利用率 = C P U 的有效工作时间 C P U 的有效工作时间 + C P U 空闲等待时间 \small CPU的利用率=\frac{CPU的有效工作时间}{CPU的有效工作时间+CPU空闲等待时间} CPU的利用率=CPU的有效工作时间+CPU空闲等待时间CPU的有效工作时间
-
系统吞吐量。表示单位时间内CPU完成作业的数量。长作业需要消耗较长的处理机时间,因此会降低系统的吞吐量。而对于短作业,需要消耗的处理机时间较短,因此能提高系统的吞吐量。调度算法和方式的不同,也会对系统的吞吐量产生较大的影响。
-
周转时间。指从作业提交到作业完成所经历的时间,是作业等待、在就绪队列中排队、在处理机上运行及输入/输出操作所花费时间的总和。周转时间的计算方法如下:
周转时间 = 作业完成时间 − 作业提交时间 \small 周转时间=作业完成时间-作业提交时间 周转时间=作业完成时间−作业提交时间
- 平均周转时间是指多个作业周转时间的平均值:
平均周转时间 = 作业 1 的周转时间 + . . . + 作业 n 的周转时间 n \small 平均周转时间=\frac{作业1的周转时间+...+作业n的周转时间}{n} 平均周转时间=n作业1的周转时间+...+作业n的周转时间
- 带权周转时间是指作业周转时间与作业实际运行时间的比值:
带权周转时间 = 作业周转时间 作业实际运行时间 \small 带权周转时间=\frac{作业周转时间}{作业实际运行时间} 带权周转时间=作业实际运行时间作业周转时间
-
等待时间。指进程处于等处理机的时间之和,等待时间越长,用户满意度越低。处理机调度算法实际上并不影响作业执行或输入/输出操作的时间,只影响作业在就绪队列中等待所花的时间。因此,衡量一个调度算法的优劣,常常只需简单地考察等待时间。
-
响应时间。指从用户提交请求到系统首次产生响应所用的时间。在交互式系统中,周转时间不是最好的评价准则,一般采用响应时间作为衡量调度算法的重要准则之一。从用户角度来看,调度策略应尽量降低响应时间,使响应时间处在用户能接受的范围之内。
2.2.3 调度的实现
1. 调度程序(调度器)
- 排队器。将系统中的所有就绪进程按照一定的策略排成一个或多个队列,以便于调度程序选择。每当有一个进程转变为就绪态时,排队器便将它插入到相应的就绪队列中。
- 分派器。依据调度程序所选的进程,将其从就绪队列中取出,将CPU分配给新进程。
- 上下文切换器。在对处理机进行切换时,会发生两对上下文的切换操作:第一对,将当前进程的上下文保存到其PCB中,再装入分派程序的上下文,以便分派程序运行;第二对,移出分派程序的上下文,将新选进程的CPU现场信息装入处理机的各个相应寄存器。
2. 调度的时机、切换与过程
调度程序是操作系统内核程序。
不能进行进程的调度与切换的情况
- 在处理中断的过程中。中断处理过程复杂,在实现上很难做到进程切换,而且中断处理是系统工作的一部分,逻辑上不属于某一进程, 不应被剥夺处理机资源。
- 进程在操作系统内核临界区中。进入临界区后,需要独占式地访问,理论.上必须加锁,以防止其他并行进程进入,在解锁前不应切换到其他进程,以加快临界区的释放。
- 其他需要完全屏蔽中断的原子操作过程中。如加锁、解锁、中断现场保护、恢复等原子操作。在原子过程中,连中断都要屏蔽,更不应该进行进程调度与切换。
应该进行进程调度与切换的情况
1)发生引起调度条件且当前进程无法继续运行下去时,可以马上进行调度与切换。若操作系统只在这种情况下进行进程调度,则是非剥夺调度。
2)中断处理结束或自陷处理结束后,返回被中断进程的用户态程序执行现场前,若置上请求调度标志,即可马上进行进程调度与切换。若操作系统支持这种情况下的运行调度程序,则实现了剥夺方式的调度。
2.2.4 典型的调度算法
1. 先来先服务(FCFS)调度算法
在进程调度中,FCFS调度算法每次从就绪队列中选择最先进入该队列的进程,将处理机分配给它,使之投入运行,直到运行完成或因某种原因而阻塞时才释放处理机。
它不能作为分时系统和实时系统的主要调度策略。
FCFS调度算法的特点
- FCFS调度算法的特点是算法简单,但效率低;
- 对长作业比较有利,但对短作业不利(相对SJF和高响应比);
- 有利于CPU繁忙型作业,而不利于IO繁忙型作业。
2. 短作业优先(SJF)调度算法
短作业(进程)优先调度算法是指对短作业(进程)优先调度的算法。短作业优先(SJF)调度算法从后备队列中选择一 个或若干估计运行时间最短的作业,将它们调入内存运行。
SJF调度算法的缺点
- 该算法对长作业不利,SJF调度算法中长作业的周转时间会增加。更严重的是,若有一长作业进入系统的后备队列,由于调度程序总是优先调度那些(即使是后进来的)短作业,将导致长作业长期不被调度“饥饿”现象,注意区分“死锁”,后者是系统环形等待,前者是调度策略问题)。
- 该算法完全未考虑作业的紧迫程度,因而不能保证紧迫性作业会被及时处理。
- 由于作业的长短是根据用户所提供的估计执行时间而定的,而用户又可能会有意或无意地缩短其作业的估计运行时间,致使该算法不一定能真正做到短作业优先调度。
SJF调度算法的平均等待时间、平均周转时间最少。
3. 优先级调度算法
在进程调度中,优先级调度算法每次从就绪队列中选择优先级最高的进程,将处理机分配给它,使之投入运行。
优先级调度算法分类:
- 非抢占式优先级调度算法。当一个进程正在处理机上运行时,即使有某个优先级更高的进程进入就绪队列,仍让正在运行的进程继续运行,直到由于其自身的原因而让出处理机时(任务完成或等待事件),才把处理机分配给就绪队列中优先级最高的进程。
- 抢占式优先级调度算法。当一个进程正在处理机上运行时,若有某个优先级更高的进程进入就绪队列,则立即暂停正在运行的进程,将处理机分配给优先级更高的进程。
进程优先级
- 静态优先级。优先级是在创建进程时确定的,且在进程的整个运行期间保持不变。确定静态优先级的主要依据有进程类型、进程对资源的要求、用户要求。
- 动态优先级。在进程运行过程中,根据进程情况的变化动态调整优先级。动态调整优先级的主要依据有进程占有CPU时间的长短、就绪进程等待CPU时间的长短。
进程优先级设置原则
- 系统进程>用户进程。系统进程作为系统的管理者,理应拥有更高的优先级。
- 交互型进程>非交互型进程(或前台进程>后台进程)。大家平时在使用手机时,在前台运行的正在和你交互的进程应该更快速地响应你,因此自然需要被优先处理。
- I/O型进程>计算型进程。所谓I/O型进程,是指那些会频繁使用I/O设备的进程,而计算型进程是那些频繁使用CPU的进程(很少使用I/O设备)。我们知道,IO 设备(如打印机)的处理速度要比CPU慢得多,因此若将I/O型进程的优先级设置得更高,就更有可能让I/O设备尽早开始工作,进而提升系统的整体效率。
4. 高响应比优先调度算法
在每次进行作业调度时,先计算后备作业队列中每个作业的响应比,从中选出响应比最高的作业投入运行。
响应比公式
响应比 = 等待时间 + 要求服务时间 要求服务时间 \small响应比= \frac{等待时间+要求服务时间}{要求服务时间} 响应比=要求服务时间等待时间+要求服务时间
根据公式可知:
- 作业的等待时间相同时,要求服务时间越短,响应比越高,有利于短作业,因而类似于SJF。
- 要求服务时间相同时,作业的响应比由其等待时间决定,等待时间越长,其响应比越高,因而类似于FCFS。
- 对于长作业,作业的响应比可以随等待时间的增加而提高,当其等待时间足够长时,也可获得处理机,克服了“饥饿”现象。
5. 时间转轮调度算法
时间片轮转调度算法主要适用于分时系统。在这种算法中,系统将所有就绪进程按FCFS策略排成一个就绪队列,调度程序总是选择就绪队列中的第一个进程执行,但仅能运行一个时间片,如50ms。在使用完一 个时间片后,即使进程并未运行完成,它也必须释放出(被剥夺)处理机给下一个就绪进程,而被剥夺的进程返回到就绪队列的末尾重新排队,等候再次运行。
在时间片轮转调度算法中,时间片的大小对系统性能的影响很大。
- 若时间片足够大,以至于所有进程都能在一个时间片内执行完毕,则时间片轮转调度算法就退化为先来先服务调度算法。
- 若时间片很小,则处理机将在进程间过于频繁地切换,使处理机的开销增大,而真正用于运行用户进程的时间将减少。
因此,时间片的大小应选择适当,时间片的长短通常由以下因素确定:系统的响应时间、就绪队列中的进程数目和系统的处理能力。
6. 多级队列调度算法
该算法在系统中设置多个就绪队列,将不同类型或性质的进程固定分配到不同的就绪队列。
每个队列可实施不同的调度算法,因此,系统针对不同用户进程的需求,很容易提供多种调度策略。同一队列中的进程可以设置不同的优先级,不同的队列本身也可以设置不同的优先级。在多处理机系统中,可以很方便为每个处理机设置一个单独的就绪队列,每个处理机可实施各自不同的调度策略,这样就能根据用户需求将多个线程分配到一个或多个处理机上运行。
7. 多级反馈队列调度算法 (融合了前几种算法的优点)
通过动态调整进程优先级和时间片大小,多级反馈队列调度算法可以兼顾多方面的系统目标。
多级反馈队列调度算法实现思想
多级反馈队列调度算法的实现思想如下:
- 设置多个就绪队列,并为每个队列赋予不同的优先级。第1级队列的优先级最高,第2级队列的优先级次之,其余队列的优先级逐个降低。
- 赋予各个队列的进程运行时间片的大小各不相同。在优先级越高的队列中,每个进程的时间片就越小。例如,第i+ 1级队列的时间片要比第i级队列的时间片长1倍。
- 每个队列都采用FCFS算法。当新进程进入内存后,首先将它放入第1级队列的末尾,按FCFS原则等待调度。当轮到该进程执行时,如它能在该时间片内完成,便可撤离系统。若它在一个时间片结束时尚未完成,调度程序将其转入第2级队列的末尾等待调度;若它在第2级队列中运行一个时间片后仍未完成,再将它放入第3级队列…以此类推。当进程最后被降到第n级队列后,在第n级队列中便采用时间片轮转方式运行。
- 按队列优先级调度。仅当第1级队列为空时,才调度第2级队列中的进程运行;仅当第1~i-1级队列均为空时,才会调度第i级队列中的进程运行。若处理机正在执行第i级队列中的某进程时,又有新进程进入任何一个优先级较高的队列,此时须立即把正在运行的进程放回到第i级队列的末尾,而把处理机分配给新到的高优先级进程。
多级反馈队列的优势
- 终端型作业用户:短作业优先。
- 短批处理作业用户:周转时间较短。
- 长批处理作业用户:经过前面几个队列得到部分执行,不会长期得不到处理。
8. 调度算法小结
2.2.5 进程切换
1) 上下文切换
切换CPU到另一个进程需要保存当前进程状态并恢复另一个进程的状态,这个任务称为上下文切换。
上下文是指某一时刻CPU寄存器和程序计数器的内容。
进行上下文切换时,内核会将旧进程状态保存在其PCB中,然后加载经调度而要执行的新进程的上下文。
上下文切换实质上是指处理机从一个进程的运行转到另一个进程上运行,在这个过程中,进程的运行环境产生了实质性的变化。
上下文切换的流程
- 挂起一个进程,保存CPU上下文,包括程序计数器和其他寄存器。
- 更新PCB信息。
- 把进程的PCB移入相应的队列,如就绪、在某事件阻塞等队列。
- 选择另一个进程执行,并更新其PCB。
- 跳转到新进程PCB中的程序计数器所指向的位置执行。
- 恢复处理机上下文。
2) 上下文切换的消耗
上下文切换通常是计算密集型的,即它需要相当可观的CPU时间,在每秒几十上百次的切换中,每次切换都需要纳秒量级的时间,所以上下文切换对系统来说意味着消耗大量的CPU时间。
有些处理器提供多个寄存器组,这样,上下文切换就只需要简单改变当前寄存器组的指针。
3) 上下文切换与模式切换
用户态和内核态之间的切换称为模式切换,而不是上下文切换,因为没有改变当前的进程。
模式切换与上下文切换是不同的,模式切换时,CPU逻辑上可能还在执行同一进程。 用户进程最开始都运行在用户态,若进程因中断或异常进入核心态运行,执行完后又回到用户态刚被中断的进程运行。
上下文切换只能发生在内核态,它是多任务操作系统中的一 个必需的特性。
调度和切换的区别
调度是指决定资源分配给哪个进程的行为,是一种决策行为;
切换是指实际分配的行为,是执行行为。一般来说,先有资源的调度,然后才有进程的切换。