进程调度算法

进程调度算法

这里首先要提及衡量进程调度算法的指标,毕竟很多算法的出现都与这些指标的需求息息相关

调度指标

1. 周转时间(Turnaround Time, TAT)

  • 定义:一个进程从 提交(Arrival)完成(Completion) 所经历的时间。

  • 计算方式: Turnaround Time=Completion Time−Arrival Time\text{Turnaround Time} = \text{Completion Time} - \text{Arrival Time}Turnaround Time=Completion Time−Arrival Time

  • 目标:希望 尽可能小,让进程尽快完成。


2. 响应时间(Response Time, RT)

  • 定义:一个进程 提交后(Arrival),直到 首次被 CPU 调度执行(First Run) 之间的时间。

  • 计算方式: Response Time=First Run Time−Arrival Time\text{Response Time} = \text{First Run Time} - \text{Arrival Time}Response Time=First Run Time−Arrival Time

  • 目标:希望 尽可能小,让进程尽快得到响应(特别适用于交互式系统)。


3. 等待时间(Waiting Time, WT)

  • 定义:进程在 就绪队列(Ready Queue) 中等待 CPU 的时间总和(不包括执行时间)。

  • 计算方式: Waiting Time=Turnaround Time−Burst Time\text{Waiting Time} = \text{Turnaround Time} - \text{Burst Time}Waiting Time=Turnaround Time−Burst Time 其中 Burst Time 是进程真正需要的 CPU 执行时间。

  • 目标:希望 尽可能小,减少 CPU 资源的浪费,提高吞吐量。


4. 吞吐量(Throughput)

  • 定义:单位时间内 CPU 处理的 进程数量

  • 计算方式: Throughput=完成的进程数总时间\text{Throughput} = \frac{\text{完成的进程数}}{\text{总时间}}Throughput=总时间完成的进程数

  • 目标:希望 尽可能大,提高系统整体效率。


5. CPU 利用率(CPU Utilization)

  • 定义:CPU 实际用于执行进程的时间占 总时间 的比例。

  • 计算方式: CPU Utilization=CPU 执行时间总时间×100%\text{CPU Utilization} = \frac{\text{CPU 执行时间}}{\text{总时间}} \times 100\%CPU Utilization=总时间CPU 执行时间×100%

  • 目标:希望 尽可能高,但通常不会达到 100%,否则可能会导致过载。

调度算法

1.FIFO

该算法如其名,first in first out,与队列的先进先出一样,先提交的进程优先进行调度,执行完一个再调度下一个。

当进程的执行时间都很短时,FIFO的平均周转时间表现很好

但是当先提交的进程的执行时间很长时,FIFO的平均周转时间表现很差,因为长任务会阻塞住短任务

而不论什么情况,FIFO的平均响应时间表现都很差,因为该算法要求一个进程完成后才能调度下一个

2.SJF(Shortest Job First)

SJF算法优先调度执行时间最短的进程,这样就能改善平均周转时间的表现,但是平均响应时间依然表现很差,而且最重要的问题是操作系统如何得知哪个进程的执行时间最短,以及如何保证执行时间长的进程不挨饿

解决问题:

1.操作系统往往使用预测算法来估算任务的执行时间,但往往这种估算不太准确

2.只使用SJF本体难以保证长任务不挨饿,必须结合其他策略和算法如多级反馈调节,老化等等

两种变体
1.非抢占式SJF

此变体在有新任务提交时,不会抢占原有正在执行的任务

但是这种算法如果有更短时间的任务提交,可能会降低平均周转时间和平均响应时间

但是这种算法仍然无法保证长任务不挨饿

2.抢占式SJF(又名SRTF,Shortest Remaining Time First)(还叫STCF Shortest Time-to-Completion First)

此变体在有新任务提交时,会比较新任务和正在进行的任务的剩余完成时间,哪个短就调度谁。

这种算法在有频繁更短新任务提交的时候,可能会一直由新任务抢占旧任务,从而使得任务难以完成,使得平均周转时间表现变差,而且抢占引起的上下文切换也会带来时间开销,使得吞吐量降低,并且长任务挨饿的问题依旧得不到解决

3.RR(Round Robin)时间片轮转

为了解决响应时间的问题,又发明出了RR算法,设置时间片长度,每个时间片轮转(在循环队列中 FIFO)调度不同的任务,

这样可以保证每个任务的响应时间短,但是平均周转时间会大打折扣

这种算法特别适合响应式的软件,如果用以上其他算法,导致一个任务长时间得不到相应,那就很难受

但是任务的频繁切换会导致上下文的切换的开销,故此种算法完成任务的时间一般要比非抢占式的算法更久

如果时间片设置得过短,那么上下文切换的时间可能等同于或超过任务的执行时间

如果时间片设置得过长,那么该算法可能趋向变成FIFO算法,导致响应时间降低

故折中一下,一般将时间片设置为CPU Burst进程在 CPU 上连续运行的一段时间,直到发生 I/O 或被调度切换)的80%

4.多级反馈队列(MLFQ)

为了平衡周转时间,响应时间和吞吐量,多级反馈队列算法出现了。

多级反馈队列设置了多个优先级队列,若是当前任务的运行时间超出了当前优先级限定的时间片,就会将其降级,这样短任务就会快速完成,而长任务也会随着执行时间增长而降低优先级,且高优先级任务可以随时抢占低优先级任务,但是当运行久了之后,长任务岂不是会挨饿,于是MLFQ在一段时间之后会重置优先级,以便长任务不会挨饿

但是若是任务执行一段时间就进行I/O阻塞住,且每次执行的时间都不超出当前优先级队列限定的时间片,岂不是会一直留在高优先级队列”欺骗“过了算法

为了解决这一问题,多级反馈队列被如此改进:

当前任务的总执行时间超出了当前优先级队列限定的时间片,就降低优先级

那么又有一个问题,在重置优先级之前,难道低优先级队列中的任务就没有机会被执行了吗?

那肯定是不会的,低优先级队列中的任务在以下情况下有机会被执行:

高优先级队列为空,或高优先级任务阻塞后队列为空,或低优先级任务时间片没有被用完

此时低优先级任务可以正常执行,但是可以随时被高优先级队列中的任务抢占

优先级重置策略
1.全局重置

每隔一段时间重置所有任务的优先级

使得所有任务都有机会执行

2.Aging(老化)

任务在等待队列中停留的时间越长,它的优先级就越高

防止单一任务挨饿

比例份额调度程序(又名公平调度程序)

这种调度程序的出现基于一个很简单的想法:调度程序的最终目标,是保证每个工作获得一定比例的CPU时间,而不是优化周转时间和调度时间

彩票调度

用彩票数代表份额,根据每个任务的CPU Burst来确定份额的多少

像是这种分配

当需要调度进程的时候,会随机(伪随机)生成一个范围中的数,用来判定调度哪一个任务

步长调度

主要概念:
  • 步长(Stride): 每个进程都有一个步长值,通常通过一个常数(如10000)除以该进程的彩票数(代表其权重)计算得出。

  • 行程值(Pass Value): 用于记录进程的累计运行程度,初始值为0。

调度过程:
  1. 选择进程: 每次调度时,选择当前行程值最小的进程运行。

  2. 更新行程值: 进程运行一个时间片后,将其行程值增加自身的步长值。

要注意的是这两种调度算法并未在操作系统中被广泛使用,可能是由于对I/O密集型任务的适配性不足

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值