时至今日,我认为System V
的进程调度器设计得是十分精妙的,这个调度器可能直接影响到后来的windows nt
系统。
简单说System V
的调度器是基于多级反馈优先级队列的,每个进程在一个优先级队列被排队,然后可能在某些时间点被反馈到别的优先级队列,调度动作很简单,就是从最高优先
级队列取出一个进程,然后将当前进程反馈到一个优先级队列,随着进行的是进程切换。调度器的关键点有二:1.
如何排队;2.
如何反馈。
System V
认为系统内部的执行绪本身在地位上就是不平等的,你不能把等待磁盘io
的任务和没啥事在计算i++
的进程等同起来,如果说有两个相同的任务,显然它们的 优先级也相等,但是一个任务非常不巧的要等待磁盘io
,而另一个任务在执行i++
(因为任务是相同的,它一会也要执行磁盘io
,但是不是现在),那么这时 它们的优先级还能相等吗?System V
认为不能,但是它们一开始的优先级确实是相等的啊!这就是System V
中一切进程的优先级是一直在动态调整的,关键看当前执行的什么性质的任务,这只是“
动态调整”
的意义之一,“
动态调整”
的另一半就是无论如何,优先级随 着时间的流逝也会调整的,即使该进程执行的任务性质没有变化,举个例子就是说,如果一个进程在3
秒内一直执行i++
,那么第一个一秒和第二个一秒以及第三 个一秒,这个进程的优先级是不同的。
定量的说一下,一个进程的优先级公式就是:
0.cpu = cpu +1;
1.cpu = cpu/2;
2.priority = (cpu/2) + base level priority;
其 中,cpu
指的是一个进程最近使用的cpu
时间,每次时钟中断运行进程的cpu
时间都会加1
,正如式子0
所示,那么式子1
是什么时候计算的呢,在 System V
中这是一个定量的测量时间,被规定为1
秒,每次过了1
秒,内核的时钟处理或其他地方会执行式子1
,这里的cpu
变量当然是当前进程的cpu
变量。至于式
子2
的执行时刻,和式子1
是一样的,只不过就不是调整一个当前进程的优先级了,而是所有用户态进程的优先级,至于内核态的优先级,简单说有两种,运行在内
核态的进程要么不阻塞,要么阻塞,不阻塞的情况下,其优先级还是用用户态优先级,阻塞的情况下,解除阻塞时该进程的优先级和阻塞的原因相关联,也即是说, 如果一个进程因为磁盘io
被阻塞了,那么它被唤醒时被赋予的优先级就比因为等待缓冲区被阻塞的进程被唤醒时赋予的优先级要高,这是确定的,从最高到低的睡
眠优先级分别为:
3.
对换-->
等待磁盘io-->
等待缓冲区-->
等待索引节点-->
等待tty
输入-->
等待tty
输出-->
等待子进程退出....
如果一个进程由于一定原因睡眠了,那么根据这个原因在它被唤醒的时候就被赋予了不同的优先级然后一直运行下去,直到一个策略点。这个策略点不同的内核可以
有不同的实现,在非抢占内核,这个策略点可能就是这个进程返回用户空间的前夕,而在抢占式内核,这个策略点就是随便一个高优先级进程就绪或者就是该进程的 时间片用尽。在这个策略点上,抢占将发生。
只要一个用户进程在运行,那么它的cpu
变量就会增加,这样在内核计算上面式子2
的时候,该增量就会被加到进程的优先级上,从而使得进程优先级降低而被抢 占,但是不能这么无情,比如n
秒以前的cpu
计时变量不应该这么无情的增加到当前,那么就出现了一个衰减函数,该衰减函数就是式子1
。
我们可以看到式子0
,1
,2
以及序列3
实际上都是具体的策略,而机制就是1.
优先级和睡眠原因的联系;2.
优先级的动态反馈调整。机制1
保证了一些任务的 紧急性以及事实上的优先级,机制2
保证了用户进程的公平,实际上机制2
可以不用任何时间片的概念就可以做到公平调度,当今linux
内核的cfs
调度器就 是没有时间片的概念,而windows nt
内核使用的也是动态优先级调整的机制,它的内核还有中断请求级的概念,包括当今solaris
内核的中断优先级的概念,是不是也是和System v
的强大调度器关系很暧昧呢?

被折叠的 条评论
为什么被折叠?



