调度器
调度器是一个操作系统的核心部分。可以比作是CPU时间的管理员。调度器主要负责选择某些就绪的进程来执行。不同的调度器根据不同的方法挑选出最适合运行的进程。目前Linux支持的调度器就有RT scheduler、Deadline scheduler、CFS scheduler及Idle scheduler等。
首先要明白为什么要引入虚拟时间
完全公平调度算法CFS依赖于虚拟时钟
CFS通过每个进程的虚拟运行时间(vruntime)来衡量哪个进程最值得被调度。CFS中的就绪队列是一棵以vruntime为键值的红黑树,虚拟时间越小的进程越靠近整个红黑树的最左端。因此,调度器每次选择位于红黑树最左端的那个进程,该进程的vruntime最小。
虚拟运行时间是通过进程的实际运行时间和进程的权重(weight)计算出来的。在CFS调度器中,将进程优先级这个概念弱化,而是强调进程的权重。一个进程的权重越大,则说明这个进程更需要运行,因此它的虚拟运行时间就越小,这样被调度的机会就越大。
进程分类
对于调度问题,传统上进程分为"I/O受限(I/O-bound)"或“CPU受限(CPU-bound)”。前者频繁地使用I/O设备(数据库服务器,想想索引,树的高度不就是io访问吗),并花费很多时间等待IO操作完成,后者需要大量CPU时间的数值计算应用程序(图像绘制)。
另一种分类法把进程区分为3类:
交互式进程:这些进程经常与用户经行交互,因此要花很多时间等待键盘鼠标操作
批处理进程:这些进程不必与用户交互,因此经常在后台运行。因为这样的进程不必被很快的响应,因此常受到调度程序的慢待
典型批处理进程是程序设计语言的编译程序、数据库搜索引擎及科学计算。
实时进程:这些进程有很强的调度需要。这样的进程绝不会被低优先级的进程阻塞。典型有视频音频应用程序、机器人控制,传感器收集。
O(n)调度
O(n)调度:内核调度算法理解起来简单:在每次进程切换时,内核依次扫描就绪队列上的每一个进程,计算每个进程的优先级,再选择出优先级最高的进程来运行;尽管这个算法理解简单,但是它花费在选择优先级最高进程上的时间却不容忽视。系统中可运行的进程越多,花费的时间就越大,时间复杂度为O(n)
O(1)调度
O(1)调度:其基本思想是根据进程的优先级进行调度。进程有两个优先级,一个是静态优先级,一个是动态优先级.静态优先级是用来计算进程运行的时间片长度的,动态优先级是在调度器进行调度时用到的,调度器每次都选取动态优先级最高的进程运行.由于其数据结构设计上采用了一个优先级数组,这样在选择最优进程时时间复杂度为O(1),所以被称为O(1)调度。
静态优先级的计算:
nice值和静态优先级之间的关系是:静态优先级=100+nice+20
而nice值的范围是-20~19,所以普通进程的静态优先级的范围是100~139
进程运行的时间片长度的计算:
静态优先级<120,基本时间片=max((140-静态优先级)*20, MIN_TIMESLICE)
静态优先级>=120,基本时间片=max((140-静态优先级)*5, MIN_TIMESLICE)
其中MIN_TIMESLICE为系统规定的最小时间片.从该计算公式可以看出,静态优先级越高(值越低),进程得到的时间片越长
动态优先级的计算:
动态优先级=max(100 , min(静态优先级 – bonus + 5 , 139))
从上面看出,动态优先级的生成是以静态优先级为基础,再加上相应的惩罚或奖励(bonus).这个bonus并不是随机的产生,而是根据进程过去的平均睡眠时间做相应的惩罚或奖励.交互性强的进程会得到调度程序的奖励(bonus为正),而那些一直霸占CPU的进程会得到相应的惩罚(bonus为负).
总结:就是费时间的优先级会变大,省时间的会变小
普通进程的动态优先级的范围是100~139,实时进程的动态优先级的范围是0~99
普通进程的优先级
CFS是Completely Fair Scheduler简称,即完全公平调度器。CFS的设计理念是在真实硬件上实现理想的、精确的多任务CPU。CFS调度器和以往的调度器不同之处在于没有时间片的概念,而是分配cpu使用时间的比例。例如:2个相同优先级的进程在一个cpu上运行,那么每个进程都将会分配50%的cpu运行时间。这就是要实现的公平。
以上举例是基于同等优先级的情况下。

本文深入探讨了Linux中CFS调度器的工作原理,包括虚拟时间、权重和优先级的概念,以及如何通过红黑树实现公平的进程调度。CFS调度器确保了每个进程都能根据其权重公平地获取CPU时间。

1269

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



