在进程世界中,CPU访问协调裁决的过程被称为调度(Scheduling)。
一、进程调度的目标:
a.进程响应时间快
b.加强交互性能
c.保证公平和避免饥饿
d.SMP调度
e.软实时调度
二、进程区分为三类:
a.交互式进程
进程与用户进行交互,比如等待键盘鼠标等操作,接收这些输入后进程必须很快被唤醒,否则用户将发现反应迟钝,平均延迟在50-150ms之间。
b.批处理进程
这些进程不必与用户交互,因此常在后台运行。
c.实时进程
这些进程有很强的调度需要,这样的进程决不会被优先级的进程阻塞。有一个很短的相应时间,且相应的时间变化很小。
三、调度类型:
SCHED_FIFO
先进先出的实时进程。当调度程序把CPU分配给进程的时候,它把该进程描述符保留在运行队列链表的当前位置。如果没有其他可运行的更高优先级实时进程,进程就继续使用CPU,想用多久就用多久,即使还有其余具有相同优先级的实时进程处于可运行状态。
SCHED_RR
时间片轮转实时进程。当调度程序把CPU分配给进程的时候,它把该进程的描述符放在运行链表的末尾。这种策略保证对所有具有相同时间优先级的SCHED_RR实时进程公平地分配CPU时间。
SCHED_NORMAL
普通的分时进程。
四、普通进程的调度:
每个普通进程均具有自己静态优先级,调度程序使静态优先级来评估系统中这个进程与其他普通进程之间调度的程度。内核用从100(最高优先级)到139(最低优先级)的数表示普通进程的静态优先级。值越大静态优先级越低。
4.1 基本时间片:
(140 - 静态优先级) * 20 静态优先级 < 120
基本时间片(ms) = {
(140 – 静态优先级) * 5 静态优先级 >= 120
从上面公式看出静态优先级本质决定进程基本时间片,静态优先级越高(其值越小),基本时间片就越长。
优先级 | 静态优先级 | Nice值 | 基本时间片 | 交互的δ值 | 睡眠的极限时间 |
最高静态优先级 | 100 | -20 | 800ms | -3 | 299ms |
高静态优先级 | 110 | -10 | 600ms | -1 | 499ms |
缺省静态优先级 | 120 | 0 | 100ms | +2 | 799ms |
低静态优先级 | 130 | +10 | 50ms | +4 | 999ms |
最低静态优先级 | 139 | +19 | 5ms | +6 | 1199ms |
4.2 动态优先级:
其值范围100(最高优先级)到139(最低优先级)的数表示普通进程的静态优先级。值越大静态优先级越低。动态优先级的调度程序在选择新进程来运行时候使用的数,与静态优先级关系如下公式:
动态优先级 = max(100 , min(静态优先级 – bonus + 5 ,139))
bonus是范围0-10的值,值小于5表示降低动态优先级以示惩罚,值大于5表示增加动态优先级以示奖赏。bonus的值依赖于过去进程平均睡眠时间。(注:平均睡眠时间是进程在睡眠状态所消耗的平均纳秒数)
平均睡眠时间 X(ms) | bonus | 粒度 |
0 ≤ X ≤ 100 | 0 | 5120 |
100 ≤ X ≤ 200 | 1 | 2560 |
200 ≤ X ≤ 300 | 2 | 1280 |
300 ≤ X ≤ 400 | 3 | 640 |
4000 ≤ X ≤ 500 | 4 | 320 |
500 ≤ X ≤ 600 | 5 | 160 |
600 ≤ X ≤ 700 | 6 | 80 |
700 ≤ X ≤ 800 | 7 | 40 |
800 ≤ X ≤ 900 | 8 | 20 |
900 ≤ X ≤ 1000 | 9 | 10 |
1s | 10 | 10 |
平均睡眠时间也被调度程序用来确定一个给定进程是交互进程还是批处理进程,如果满足下面条件则是交互进程:
动态优先级 ≤ 3×静态优先级/4+28
也可以写成:
bonus – 5 ≥ 静态优先级/4 - 28
由上面表达式可以看出,高优先级比低优先级更容易成为交互式进程。
4.3 活动和过期进程:
为避免进程饥饿,当一个进程用完它的时间片时,它还应该被没有用完时间片的低优先级进程取代。
a.活动进程
还没有用完时间片的进程。
b.过期进程
已经用完时间片的可运行进程,被禁止运行,直到所有活动进程都过期。
用完其时间片的活动批处理进程总是变成过期进程。用完其时间片的交互式进程仍然是活动进程:调度程序重填其时间片并把它留在活动进程集合中;但是,如果最老的过期进程已经等待很长时间,或者过期进程比交互进程的静态优先级高,调度程序就把用完时间片的交互式进程移到过期进程集合中;最后,活动进程集合将变为空,过期进程将有机会运行。
五、实时进程调度
每个实时进程都有一个实时优先级,范围从1(最高优先级)- 99(最低优先级)的值。调度程序总是让优先级高的进程运行,禁止低优先级运行。
如果发生以下情况,实时进程将会被另外一个进程取代:
- 进程被另外一个具有更高实时优先级的实时进程抢占。
- 进程执行阻塞操作并进入睡眠(处于TASK_INTERRUPTIBLE或TASK_UNINTERRUPTIBLE状态)
- 进程停止(处于TASK_STOPPED或TASK_TRACED状态)或被杀死(处于EXIT_ZOMBIE或EXIT_DEAD状态)
- 进程调用sched_yield自愿放弃CPU
- 进程是基于时间片轮转的实时进程(SCHED_RR),而且用完它的时间片
注:基于时间片轮转的实时进程的基本时间片长度与实时进程优先级无关,而依赖进程的静态优先级,计算与普通进程调度计算方式一样。
PS:本人也是菜鸟,自己学习了一点就分享出来,若有纰漏欢迎指正!