一般聊到进度调度算法,很多人都会讲,先来先服务算法、短作业优先算法、高响应比优先调度算法等算法。但是Linux服务器用的是哪种呢?
进程分类
进程分为实时进程和普通进程。
实时进程: 归一化优先级为0~98的进程; 比较少被用到。
普通进程: 归一化优先级为100~139的进程,默认值是120; 使用nice值计算得到,nice范围是-20~19,nice默认值是0。
调度算法
实时进程的调度算法
实时进程 使用优先级+SCHED_FIFO 或者 优先级+SCHED_RR算法。
优先级高的进程先执行。在相同优先级的情况下,可以选择SCHED_FIFO或者SCHED_RR。
1、SCHED_FIFO:先进先出。直到先被执行的进程变为非可执行状态,后来的进程才被调度执行。
2、SCHED_RR:轮转调度。内核为实时进程分配时间片。
这两种调度策略仅仅针对于相同优先级的多个实时进程同时处于可执行状态的情况。
普通进程的调度算法
普通进程使用SCHED_NORMAL(还有其他的,这个是默认策略),完全公平调度算法CSF。该算法使用以下公式计算一个vruntime,用于决定调度的先后顺序:
shell
vruntime = (实际运行时间 * 1024) / 进程权重值
进程的vruntime越小,越容易被调度到。
所以实际运行时间越少或者进程权重越高越容易被调度到。
其中,进程权重值通过优先级计算得出,优先级越高,进程权重值越大。 而实际运行时间,则通过这个公式计算:
shell
运行时间 =
调度周期 * (进程权重值 / 所有进程权重值之和)
这样既可以保证到以前占用CPU时间短的进程,下次可以优先调度;又可以避免短作业一直占用着CPU; 还能保证高优先级进程也获得更多的执行时间。这就是CFS的主要思想。
为何vruntime越小的进程,越容易被调度到?
因为进程会被维护到一个以 vruntime 为顺序的红黑树中,每次取vruntime最小的进程调度,所以进程的vruntime越小,越容易被调度到。
进程优先级
上面提到的调度算法都有涉及到优先级,那么下面我们来讲讲Linux进程优先级的计算
概念
在聊优先级前,有个名词需要说明,就是归一化优先级。
归一化优先级是内核统一化的优先级。数值越小 , 优先级越高。下面讲到的优先级高低,都基于归一化优先级比较得出。
内核优先级参数
NICE_WIDTH宏代表nice值取值范围(最大值-最小值),值是40。
MAX_RT_PRIO宏是代表实时进程(realtime)优先级最大值,值是100。
MAX_USER_RT_PRIO等于MAX_RT_PRIO
C
#define MAX_NICE 19
#define MIN_NICE -20
#define MAX_USER_RT_PRIO 100
#define MAX_RT_PRIO MAX_USER_RT_PRIO
#define NICE_WIDTH (MAX_NICE - MIN_NICE + 1) //40
#define DEFAULT_PRIO (MAX_RT_PRIO + NICE_WIDTH / 2) //120
实时进程优先级
实时进程归一化优先级通过rt_priority计算得到:
实时进程归一化优先级 = MAX_RT_PRIO - 1 - rt_priority
所以rt_priority取值越高,实时进程的优先级越高。
普通进程优先级
普通进程归一化优先级,通过nice值计算得到。默认值是DEFAULT_PRIO(120),nice是0。
bash
普通进程归一化优先级 =
nice值 + MAX_USER_RT_PRIO + NICE_WIDTH / 2
带入计算一下就知道范围是 100~139(所以内核里面的 nice 取值范围是 -20~19)。
所以nice越小,普通进程的优先级越高。
工具中进程优先级值说明
工具的进程优先级和Linux中的归一化优先级的值并不一致。比如top命令
PR代表priority优先级;NI是代表nice的意思。top命令PR数字越小,优先级越高。(PR=归一化优先级-100)
实时进程PR是负值,范围在-100和-2之间,其中最高优先级-100显示为RT。
普通进程PR范围是0到39,对应用户设置的NI值是-20到19。
对于一个实时进程来说,PR与NI无关。
对于一个普通进程来说,PR的值等于NI的值加20,即:PR=NI+20。所以你就会发现,当进程的NI为0,PR就是20;NI为-20,PR就是0。我们平时启动的一个进程,如果没有特意去指定任务优先级的话,默认情况下,都是普通任务进程,NI的值为0,PR为20。
总结
Linux的调度算法分为实时进程和普通进程的调度算法。
实时进程使用优先级+SCHED_FIFO 或者 优先级+SCHED_RR算法。普通进程使用完全公平调度算法。
实时进程的优先级由rt_priority决定,rt_priority越大,优先级越高。
普通进程的优先级由nice值决定,nice越小,优先级越高。
其他概念说明:
rt_priority:RT调度算法类的优先级,也叫实时优先级,其值与用户空间传进来的值一致(用户空间使用 sched_setparam 等函数传递),取值范围 1~99。数值越大 , 优先级越高。
静态优先级:因为它不会随着时间而改变,内核不会修改它,只能通过系统调用nice值去修改。所以叫静态优先级。普通进程的归一化优先级就是静态优先级。
优先级范围:Linux实际上实现了140个优先级范围,取值范围是从0-139。