进程调度, 一个调度器的自白

我是一个进程调度器。算法

个人职责是调度计算机内全部的进程,为他们分配 CPU 资源。并发

1. 批处理时代

想当初,操做系统创造我时,只是打算让我用 FCFS 调度算法,简单维护下进程的秩序。但我后来的发展,远远超过了他的想象。性能

1.1 FCFS

所谓 FCFS 就是「先来先服务(First Come First Serve)」,每一个进程按进入内存的时间前后排成一队。每当 CPU 上的进程运行完毕或者阻塞,我就会选择队伍最前面的进程,带着他前往 CPU 执行。操作系统

就拿这几个进程来讲吧:设计

按照 FCFS 算法,我就会就按 A,B,C,D,E这样的顺序来将他们送往 CPU:blog

这一算法听起来简单又公平,然而好景不长,我收到了一个短进程的抱怨:”上次我前面排了一个长进程,等了足足 200 秒他才运行完。我只用 1 秒就运行结束了,就由于等他,我多花了这么长时间,太不值得了。”队列

我仔细一想, FCFS 算法确实有这个缺陷——短进程的响应时间太长了,用户交互体验会变差。进程

因此我决定,更换调度算法。内存

1.2 SPN

此次我设计的算法叫作「短任务优先」(Shortest Process Next,SPN)。每次选择预计处理时间最短的进程。所以,在排队的时候,我会把短进程从队列里提到前面。资源

这一次,短进程获得了很好的照顾,进程的平均响应时间大大下降,我和操做系统都很满意。

但长进程们不干了:那些短进程每天插队,致使他们常常得不到 CPU 资源,形成了「饥饿」现象。

取消 SPN 算法的呼声愈来愈高。

这但是个大问题。FCFS 虽然响应时间长,但最后全部进程必定有使用 CPU 资源的机会。但 SPN 算法就不同了,若是短进程源源不断加入队列,长进程们将永远得不到执行的机会——太可怕了。

所以,短任务优先算法须要获得改进。有什么方法既能照顾短进程,又能照顾长进程呢?

1.3 HRRN

通过和操做系统的讨论,咱们决定综合考量进程的两个属性:等待时间要求服务时间——等待时间长,要求服务时间短(就是短进程)的进程更容易被选中。

为了量化,咱们制定了一个公式:响应比 = (等待时间+要求服务时间)/ 要求服务时间。响应比高的算法会先执行。咱们称之为「高响应比优先」(Highest Response Ratio Next,HRRN)。

这个算法获得了长短进程的一致好评。虽然个人工做量增长了(每次调度前,我都要从新计算全部等待进程的响应比)但为了进程们的公平性,这一切都是值得的。

2. 并发时代

新时代到了。

随着计算机的普及,我的用户大量增加,并发,即一次运行多个程序的需求出现了。这可难倒我了——处理器只有一个,怎么运行多个程序?

所幸 CPU 点醒了我:“我如今的运算速度既然这么快,何不发挥这项长处,弄一个「伪并行」出来?“

“伪并行?什么意思”

“就是看起来像并行,实际上仍是串行。每一个进程短期交替使用个人资源,但在人类看来,这些进程就像在「同时」运行。”

我恍然大悟。

2.1 RR

通过 CPU 的提醒,我很快制定出了新的调度算法——时间片轮转算法(Round Robin,RR)。

在这个算法里,每一个进程将轮流使用 CPU 资源,只不过在他们开始运行时,我会为他们打开定时器,若是定时器到时间(或者执行阻塞操做),进程将被迫「下机」,切换至下一个进程。至于下一个进程的选择嘛,直接用 FCFS 就行了。

新的算法必然会面临新的问题,如今个人问题就是,时间片的长度怎么设计?

直观来看,时间片越短,固定时间里可运行的进程就越多,可 CPU 说过,切换进程是要消耗他很多指令周期的,时间片太短会致使大量 CPU 资源浪费在切换上下文上。时间片过长,短交互指令响应会变慢。因此具体怎么取,还得看交互时间大小(感受像没说同样,但至少给了个标准嘛)。

这一阶段,个人工做量大大提高——之前十几秒都不用切换一次程序,如今倒好,一秒钟就得切换数十次。

2.2 VRR

时间片轮转算法看起来十分公平——全部的进程时间片都是同样的。但事实真是这样吗?

I/O 密集型进程不这么认为,他对我说:“调度器大哥,时间片轮转没有照顾到咱们这类进程啊!咱们常常在 CPU 没呆到一半时间片,就遇到了阻塞操做,被你赶下去。并且咱们在阻塞队列,每每要停留很长时间。等阻塞操做结束,咱们还得在就绪队列排好长时间队。那些处理器密集型进程,使用了大部分的处理器时间,致使咱们性能下降,响应时间跟不上”

考虑到这些进程的要求,我决定为他们建立一个新的辅助队列。阻塞解除的进程,将进入这个辅助队列,进行进程调度时,优先选择辅助队列里的进程。

这就是「虚拟轮转法」(Virtual Round Robin,VRR)。

从后来实际性能结果来看,这种方法确实优于轮转法。我颇为自豪。

2.3 优先级调度

有一天,操做系统突然找到我,神神秘秘的说:“调度器啊,你是知道的,我要给整个系统提供服务,可最近用户进程太多,致使个人服务进程有时候响应跟不上。我有点担忧这会给系统稳定性形成影响。”

我一听,这但是个大事,系统不稳定那还得了?调度算法得换!

既然要让操做系统的服务获得足够的运行资源,那就,干脆让他们具备最高的 CPU 使用优先权吧。

优先级调度算法就此产生了。

我向你们作出了规定——每一个进程将被赋予一个优先级,本身根据本身的状况肯定优先级数值,可是,用户进程的优先级不许高于内核进程的优先级。

切换程序的时候,我会从优先级 1 的队列里选择一个进程,若是优先级 1 队列为空,才会选择优先级 2 中的进程,以此类推。

固然,为了保证低优先级进程不会饥饿,我会调高等待时间长的进程的优先级。

使用这个算法,我更忙碌了,不只须要大量切换进程,还须要动态调节优先级。可能这就是能力越大,责任越大吧。

不过我知道,正是由于个人存在,人类才能在计算机上运行多道程序——这令我感到自豪。

但愿你在看完个人文章以后有所收获。

感谢你的阅读,咱们后会有期!

声明:原创文章,未经受权,禁止转载

相关文章
相关标签/搜索