Skip to content

SJF 短作业优先调度

2026 大纲 二(二)4 CPU 调度算法SJF(短作业优先)及其抢占式变体 SRTF(最短剩余时间优先)。指标口径与算例数据沿用 调度的基本概念与目标

交互可视化

加载可视化中...

长作业堵住短作业,那就先跑短的

FCFS 的病根很清楚:护航效应——一个长作业排在前面,后面一串短作业全被堵住。

修法看起来很直接:别按到达顺序排,按作业长短排,短的先跑。 这就是 SJF。

它确实有效,而且效果不是"差不多好一点"——可以证明它在平均等待时间上是最优的。 论证很短:把相邻的两个交换一下,总等待时间的变化量恰好是"后者服务时间 − 前者服务时间"; 只要后面那个更短,交换就一定更优。反复交换的终点,就是按服务时间升序排列。

⚠️ 但这个最优性有个前提:所有进程同时到达。到达时刻不同时, 非抢占的 SJF 就不再最优了——它的抢占版 SRTF(比较剩余时间)才是。

而 SRTF 之所以能抢占,正好印证了上一节那条通用判据: 运行者的剩余时间只减、等待者的键不变,两者差距越拉越大, 所以抢占检查只需要在新进程到达的那一刻做一次——这直接决定了做题时的动作。

代价也很明确,而且是两笔。第一笔是饥饿:只要短作业源源不断,长作业就永远排不上。 第二笔更根本——它要求预知服务时间,而这在真实系统里根本做不到, 只能靠历史数据做指数加权移动平均去猜,而猜就意味着可能猜错。

一、SJF 与 SRTF 的分界

变体名称比较键抢占性
SJF短作业优先进程的总服务时间非抢占式
SRTF最短剩余时间优先(Shortest Remaining Time First)进程的剩余服务时间抢占式

剩余时间会随运行而减小,所以 SRTF 每次比较的对象都在变,抢占才有意义。而抢占检查只需在新进程到达时做一次——推导是:运行者的剩余时间只减、等待者的键不变,两者差距只会越拉越大,中途不可能出现超越,所以只有新进程进来时才可能改变胜负。这条直接决定了做题时的动作。

二、最优性:为什么"短的先做"能压低平均等待时间

结论:只要执行序列里还存在"长在前、短在后"的相邻对,当前顺序就不是最优的;反复交换直到不存在这样的相邻对,序列就是按服务时间升序排列的——这正是 SJF。

这条结论有一个两行的严格论证(相邻交换论证),也解释了"同时到达"这个前提为什么不能漏:论证假设"排在后面的进程随时可换到前面",而进程未到达时根本换不上来。

相邻交换论证的完整推导,以及用算例数据的逐步验证(想弄清最优性为什么成立、前提从哪来时展开)

设所有进程同时到达,某个执行顺序里相邻的两个进程为 X(服务时间 a)和 Y(服务时间 b),X 在前。设排在它俩之前的所有进程总服务时间为 P

  • 交换前X 等待 PY 等待 P+a,两者等待之和 =2P+a
  • 交换后Y 等待 PX 等待 P+b,两者等待之和 =2P+b

排在它俩之后的所有进程不受影响——因为无论谁先谁后,这两个进程执行完的时刻都是 P+a+b

所以交换带来的总等待时间变化量是 bab<a(后面那个更短),交换后总等待时间严格减少。

用算例数据验证(把四个进程都改成 t=0 同时到达,服务时间 7、4、1、4):

  • FCFS 顺序 P1→P2→P3→P4:总等待 0+7+11+12=30
  • 交换开头相邻的一对(P1 长、P2 短)得 P2→P1→P3→P4:总等待 0+4+11+12=27,减少了 74=3,与 ab=3 吻合
  • 一直交换到升序 P3→P2→P4→P1(1、4、4、7):总等待 0+1+5+9=15,是 24 种排列中的最小值

三、无法预知服务时间怎么办:指数加权移动平均

SJF 有一个无法回避的问题:要比较服务时间,就得先知道服务时间,而实际系统事先并不知道一个进程要跑多久。标准解法是用历史行为预测未来

τn+1=αtn+(1α)τn
符号含义
tnn实际占用 CPU 的时长(已发生,可测量)
τn对第 n 次时长的预测
τn+1对下一次时长的预测值,即调度时拿来比较的那个数
α[0,1]权重,决定"最近一次实测"与"历史积累"谁说了算

把递推式展开一次就能看清它在干什么:

τn+1=αtn+(1α)αtn1+(1α)2αtn2++(1α)nτ1

每往前推一次权重就乘一个 (1α)<1——越久远的历史权重按指数衰减。它既用上了全部历史,又只需保留一个 τ 值即可递推,这是它能进内核的关键。

α 的两个边界:α=0τn+1=τn,完全不看实测、等于放弃预测;α=1τn+1=tn,只看最近一次、对波动极其敏感。常取 α=1/2

什么时候不适用:这个公式假设进程行为有惯性。对于行为模式突变的进程——比如一个交互程序突然开始做大批量计算——预测值会在相当一段时间里持续偏低,SJF 会误把它当短作业反复优先调度。这也是实际系统更倾向 多级反馈队列 的原因:它不预测,而是看进程实际跑了几个时间片再降级,用事后行为代替事前预测。

预测器跑七轮的实际形态:它抗噪声,但对真实趋势的跟随有滞后(想看 α 的取舍落到数字上时展开)

τ1=10α=1/2

第 n 次实测 tn预测下一次 τn+1=12tn+12τn
160.5×6 + 0.5×10 = 8
240.5×4 + 0.5×8 = 6
360.5×6 + 0.5×6 = 6
440.5×4 + 0.5×6 = 5
5130.5×13 + 0.5×5 = 9
6130.5×13 + 0.5×9 = 11
7130.5×13 + 0.5×11 = 12

前四次实测在 4~6 之间波动,预测值稳稳收在 5~6;第 5 次突然跳到 13,预测值不会立刻跟上(只到 9),而是用几次的时间逐步逼近。若把 α 调大,跟随快了,但一次异常抖动也会立刻污染预测。

四、缺点

缺点说明判据
可能饥饿长作业可能永远得不到执行排在它前面的进程数可以无限增长(不断有更短的作业到达)
无法预知服务时间只能靠预测,预测就有误差见上一节;估计过低还可能被系统按时终止
对长作业不公平完全忽视等待时间一个已等了很久的长作业,其等待时间在比较中权重为 0
不能保证紧迫性完全不看紧迫程度紧急但耗时长的任务会被一直推后

第三条正是 HRRN 要修补的:把等待时间重新加回比较键里。

同一组数据跑 SJF 与 SRTF:两张甘特图与三算法横向对比(想核对做题步骤、或看抢占把哪个指标改了时展开)
进程到达时间服务时间
P107
P224
P341
P454

非抢占 SJF。 t=0 时只有 P1 到达,别无选择,且非抢占意味着这个决定不再更改,P1 跑满 7 个单位。t=7 时 P2/P3/P4 均已到达,比较服务时间 4、1、4,选 P3。t=8 时 P2 与 P4 都是 4,按"相等时先到者先跑"选 P2。

时间区间0–77–88–1212–16
执行进程P1P3P2P4
进程完成时间周转时间带权周转时间等待时间响应时间
P1777/7 = 1.0000
P3844/1 = 4.0033
P2121010/4 = 2.5066
P4161111/4 = 2.7577
平均8.002.564.004.00

抢占 SRTF。 只在 t=2、4、5 三个到达时刻各比较一次:

时刻事件当前运行者剩余新到者服务时间判断
t=0P1 到达P1: 7只有它,执行 P1
t=2P2 到达P1 剩 5P2: 44 < 5,抢占,执行 P2
t=4P3 到达P2 剩 2P3: 11 < 2,抢占,执行 P3
t=5P3 完成且 P4 到达就绪:P2 剩 2、P4 剩 4、P1 剩 5选最小者 P2
t=7P2 完成就绪:P4 剩 4、P1 剩 5选 P4
t=11P4 完成只剩 P1执行 P1 至 16
时间区间0–22–44–55–77–1111–16
执行进程P1P2P3P2P4P1
进程完成时间周转时间带权周转时间等待时间(周转−服务)响应时间
P1161616/7 ≈ 2.2990
P2755/4 = 1.2510
P3511/1 = 1.0000
P41166/4 = 1.5022
平均7.001.513.000.50

注意 P1 这一行:它的响应时间是 0(t=0 就上了 CPU),等待时间却是 9。抢占式下这两个数必然分开,等待时间只能用「周转 − 服务」算。

算法平均周转平均带权周转平均等待平均响应
FCFS8.753.504.754.75
SJF(非抢占)8.002.564.004.00
SRTF(抢占)7.001.513.000.50

SJF 相对 FCFS 的降幅在带权周转上大得多(3.50 → 2.56),因为它优先照顾的正是"服务时间小、最怕等"的那类进程。SJF 的平均周转 8.00 而 SRTF 还能压到 7.00,这也是"非抢占 SJF 需要同时到达才最优"的反例。

考点速记

  1. SJF 从已到达的进程中选总服务时间最短者(非抢占)SRTF 比较剩余时间(抢占)
  2. ⚠️SRTF 的抢占只发生在新进程到达的时刻——运行者的键(剩余时间)只减、等待者的键不变,两者差距越拉越大,中途不可能出现超越。这直接决定了做题时只需在每个到达时刻检查一次。
  3. 相邻交换论证给出最优性:交换相邻一对的总等待变化量是"后者服务时间 − 前者服务时间",反复交换的终点就是按服务时间升序。
  4. ⚠️非抢占 SJF 的最优性以"所有进程同时到达"为前提;到达时刻不同时,SRTF 才是最优的
  5. 四条缺点可能饥饿(短作业源源不断则长作业永远排不上)、无法预知服务时间对长作业不公平不能保证紧迫任务及时处理
  6. 服务时间未知时用指数加权移动平均预测(历史权重指数衰减,只需保留一个 τ 值),代价是抗噪声但跟随滞后

这一节在真题里被考过的形式

只出过一道题,而且是与 FCFS 对照着考的。

  • 给四个作业的到达时刻与运行时间,比较 FCFS 与 SJF 的平均周转时间(2017-23,与 FCFS 共享)。⚠️ 唯一的坑是"已到达"这个前提——SJF 挑的是当前已经到达且未完成的作业里最短的那个,不能挑一个还没来的,哪怕它更短。做法:按时刻往前推,每次 CPU 空出来时先圈出此刻已到达的集合,再在集合里挑。
  • 另外,SJF 与 SRTF 是"哪些算法会饥饿"这类判断题的固定素材(2014-23 在调度的基本概念讲),答案是两个都会

复习优先级必须会手算,且要分清 SJF 与 SRTF。 第二条(抢占只在新进程到达时检查) 是 SRTF 手算的全部技巧;第四条(最优性的前提)是概念题的落点。 指数加权移动平均至今没考过计算,理解它"为什么抗噪但滞后"即可。

易错:SJF 手算时挑了一个还没到达的更短作业。只能在已到达的集合里挑

易错:认为非抢占 SJF 在任何情况下平均等待时间最优。前提是所有进程同时到达;否则要用 SRTF。

易错:SRTF 手算时在每个时刻都做抢占检查。只需在新进程到达的时刻检查——其余时刻不可能发生超越。

易错:认为 SJF 不会饥饿。——短作业源源不断时长作业永远排不上。

易错:把 SJF 比较的键说成剩余时间。SJF 比总服务时间,SRTF 才比剩余时间

教材出处
  • 汤小丹《计算机操作系统》3.2.3 先来先服务(FCFS)和短作业优先(SJF)调度算法(SJF 以作业长短定优先级;四条缺点:必须预知运行时间、对长作业不利且可能饥饿、无法人机交互、未考虑紧迫程度),印刷 p90

相关知识

调度的基本概念与目标FCFS 先来先服务调度时间片轮转调度高响应比优先调度多级反馈队列调度

真题练习