日期:2014-05-16  浏览次数:20828 次

Linux进程调度策略

从Linux2.5开始Linux实现了0(1)调度算法,  算法的思想要点在于设定动态的nice值确定优先级, 在优先级数组调度(数组最大长度是固定常数)     简而言之,不管系统中有多少进程需要调度都可以在o(1)的时间复杂度内完成调度,是不是很吊啊?但是实践证明(我没证明,文献说的) o(1)对i/o交互型的调度体验上表现很差  轮转周期很不灵活,主要原因在于调度出发点采用粒度很大时间片进行轮换,诚然整体负载会比较好,但是对于i/o交互型的,我们理想的调度策略是采用处理器使用比而不是时间片来分配,  理解这一点我们可以无限极端假设到调度时候进程上下文切换的时间成本为零,这样我们如果能做到以最小的时间粒度分配保证各个同级进程的处理器相同的使用比(而不是用大片的时间片去轮换)  那么我们此时的并发体验是最好的。当然实际上上下文切换的成本不可小事,CFS算法在这方面做了很好的折衷。

linux2.6.23开始调度策略加入了全新的CFS调度算法,上一段已经说了调度的出发点,重复一下两个要点  同优先级的进程以处理器使用比为调度出发点,(而不是分配时间片,时间片的调度 切换时很不灵活,特别是I/O交互上体验上)  CFS(完全公平调度策略) 

CFS 用vruntime存放虚拟运行时间,vruntime记录了一个程序运行了多久,按照公平调度算法,理想状态下,同一优先级的vruntime应该保持一样,但我们无法做到绝对理想,我们用红黑树记录和保存vruntime的值,按照模型,我们每次取最小的来运行,这样做的原因就是为了让大家的vruntime尽量保持一样大小。 红黑树作为一种平衡二叉树的变种,最小节点在最左下的叶子节点,相对于平衡二叉树,删除和插入调整的节点数统计上更少,具有更好的统计性能。

实际上我们对不同优先级的进程的vruntime我们是放在同一个红黑树处理的,这是因为我们对vruntime进行了加权处理,从而最终将各自进程的处理器使用比维持在各自预定的目标中。