欢迎来到军工软件开发人才培养基地——学到牛牛

进程调度

时间:2024-05-06 07:01:10 来源:学到牛牛

关于进程调度需要先了解什么是进程,进程可以简单理解为正在运行的程序。而进程调度的两个关键性指标则是:响应时间与周转时间。

响应时间:

进程未运行到下次被选中运行的时间间隔。如:创建进程到第一次调度到进程的时间。再比如:进程切换后到下一次调度到该进程的时间间隔。

响应时间体现了交互感,如:敲下键盘到屏幕上出现对应的字符,自然是时间越短越好。即响应时间越短,交互性越好。

周转时间:

进程从启动开始到执行结束的时间间隔。周转时间可以体现性能,周转时间越短,从进程执行到结束所等待的时间越短。

性能和公平往往是互相矛盾的,优化性能必然会降低公平性,反之亦然。进程调度就是不断去平衡两者之间的关系,去权衡利弊。

进程的调度算法分为:先进先出(FIFO)调度算法、最短任务优先(SJF)调度算法、最短完成时间优先(STCF)调度算法、Round—Robin调度算法、高响应比优先调度算法、多级反馈队列调度算法。

 

先进先出(FIFO)调度算法:

设:有三个进程A、B、C,当他们的运行时间一致(10s)时:

平均周转时间: (10 + 20 + 30)/ 3 = 20s

平均响应时间: (0 + 10 + 10)/ 3 = 6.67s

 

当A进程运行时间为100s时:

平均周转时间: (100 + 110 + 120)/ 3 = 110s

平均响应时间: (0 + 100 + 110)/ 3 = 70s

 

此时,FIFO的缺点就很明显了。若耗时较短的进程放在耗时更长的进程之后,那么短进程将做出无谓的等待。

就像去超市买东西结账时,假如我们只买了一件商品,前面的人购物车堆满了商品。此时,我们都想让我们先结账,因为在我们看来,我们的结账速度很快。因此,这种效率很低。但如果超市开通一个新的零散结账通道给购买商品很少的客户,就可以提高效率。但很显然这是不可能的,因为超市无法对用户的商品购买量进行限制。

但这种零散结账的模式正是下一种算法:最短任务优先,让购买量较小的客户先结账。

 

最短任务优先(SJF)调度算法:

顾名思义,最短的进程先执行。按照上面的例子,如果A进程执行时间为100s,B、C不变仍为10s;A最长,所以最后执行。

平均周转时间: (10 + 20 + 120)/ 3 = 50s

平均响应时间: (0 + 10 + 20)/ 3 = 10s

 

但如果不是所有进程同时启动,而是随机启动,则此时最坏的情况就是A进程先执行,这时就又回到了最糟糕的情况:

平均周转时间: (100+(110-10) + (120 - 10))/ 3 = 103.3s

平均响应时间: (0 + (100-10) + (110-10))/ 3 = 63.3s

 

最短完成时间优先(STCF)调度算法:

在上一种算法中,仍然有可能回到最糟糕的情况。因此,我们假设进程的调度是可以抢占的,谁抢到优先权谁就先运行。那么短任务就可以在开始的时候直接运行,不需要等待很长时间,这就是最短完成时间优先调度算法。

因此,先进先出和最短任务优先都是非抢占式的,而最短完成时间是抢占式的调度算法。

 

关于抢占式,可能会有一些容易误解的地方。抢占式并不是说进程抢到CPU资源了,而是指优先级。进程调度实际上大部分都是由操作系统决定的,所谓抢占,只是表明该进程优先级要高一些,可能马上就会调度到它,下一个就是,同时也有可能除它以外还有优先级更高的进程或者和它同级的进程。

平均周转时间: (120 + (20-10) + (30-10))/ 3 = 50s

平均响应时间: (0 + 0 + 10)/ 3 = 3.3s

此算法在两项指标上都已经达到了最佳效果,这归功于抢占式。只要是抢占式,平均时间就不会比非抢占式的差。

 

Round—Robin调度算法:

其实,抢占式的响应时间还可以优化。在最短完成时间的基础上添加一个条件:指定每个进程最多运行固定的一段时间,轮询调度每一个进程,这就是“轮询调度”或“时间片轮转”。

这种“固定的时间段”就是“时间片”。如果要使用时间片的功能,就必然需要时间中断,并且时间片的长度必须是时钟周期的倍数。如: 时间中断是5s一次,那么时间片就是5s、10s、15s、20s ... ...

在上个算法的基础上添加2s的时间片,且三个进程同时启动:

平均周转时间: (120 + (30-2) + 30)/ 3 = 59.3s

平均响应时间: (0 + 2 + 4)/ 3 = 3s

高响应比优先调度算法:

高响应比优先调度算法(Highest Reponse Ratio First, HRRF)是非抢占式的,它同时考虑了每个进程的响应时间与周转时间。每次调度时,从所有进程中选出响应比最高的进程进行调度。

响应比 = (周转时间 + 响应时间)/ 周转时间

 

多级反馈队列调度算法:

多级反馈队列调度算法不需要事先知道各进程所需要的执行时间,实施过程如下:

1.设置多个就绪队列,并为其赋予不同的优先级。

 

2.赋予各队列中进程的时间片各不相同,优先级越高,时间片越小。

 

3.当一个新进程进入内存后,放入第一级队列末尾,按照FCFS原则等待调度。轮到该进程执行时,若能在该时间片内完成,便可以准备撤离系统;若在一个时间片结束时未能完成,则将其转入第二级队列末尾继续等待调度;若再不行则转入第三级队列末尾,以此类推。

 

4.当第一级队列为空时,才调度第二级队列;若在处理第n级队列中的某进程时,有一个新进程进入较高级队列中,则系统讲正在运行的进程放回第n级队列末尾,先执行较高级队列中的进程。