4、经典调度算法:先来先服务(FCFS)、最短作业优先(SJF)、优先级调度、轮转调度(RR)

调度算法这东西,说白了就是「谁先干活」的问题。

我在分拣机项目里调试过不下十种调度策略,踩过的坑比写过的代码还多。今天聊的这四种算法,是操作系统里的老面孔,但放在工业分拣场景下,每个都有它的脾气。

4.1 先来先服务(FCFS)

这是最朴素的算法。谁先到,谁先干。就像排队买饭,先来的先打菜。

核心逻辑:

  • 任务按到达时间排序
  • 非抢占式——一旦开始,必须做完
  • 实现简单,几乎零开销

分拣场景适用性:

适合包裹到达顺序稳定、处理时间差异不大的产线。比如快递分拣,每个包裹重量相近,处理时间差不多,FCFS完全够用。

⚠ 避坑指南:

我曾经在一个异形件分拣线上用了FCFS,结果一个大件卡了30秒,后面所有小件全部堵死。平均等待时间直接爆炸。记住:FCFS怕「长任务堵车」。

4.2 最短作业优先(SJF)

这个算法很聪明——谁干得快,谁先上。

你想想看,如果有个小件只需要2秒处理完,你非要等前面那个大件磨蹭20秒,是不是很亏?SJF就是解决这个问题的。

两种变体:

  • 非抢占式SJF:等当前任务做完,再挑最短的下一个
  • 抢占式SJF(SRTF):新来的任务如果更短,直接抢断当前任务
特性 非抢占式SJF 抢占式SRTF
平均等待时间 较短 最短(理论最优)
实现复杂度 高(需要保存上下文)
分拣适用性 适合已知处理时间的场景 适合实时性要求高的场景

💡 我的经验:

在分拣机里,我一般用非抢占式SJF。因为抢占式需要频繁保存机械臂的当前位置和状态,搞不好会丢包。嗯,这里要注意:SJF需要预估处理时间,不准的话反而更糟。

4.3 优先级调度

这个就有点「看人下菜碟」的意思了。

每个任务带一个优先级数字,数字越小优先级越高(或者反过来,看你怎么定义)。调度器每次挑优先级最高的任务执行。

优先级怎么定?

  • 静态优先级:任务创建时就定死。比如VIP包裹永远优先
  • 动态优先级:运行时可以调整。比如等太久的任务自动升优先级

分拣场景实战:

我记得有个冷链分拣项目,生鲜包裹必须15分钟内处理完,否则变质。我给这些包裹设了最高优先级,普通包裹排后面。效果立竿见影,损耗率从8%降到0.5%。

⚠ 致命陷阱:

优先级调度最大的坑是「饥饿」——低优先级任务永远轮不到。我曾经见过一个低优先级包裹在传送带上转了3小时没人管。解决方案?用「老化」机制,等得越久优先级越高。

4.4 轮转调度(RR)

这个算法最公平。每个任务分一个时间片,轮流执行。时间一到,不管干没干完,先让给下一个。

你想想看,就像开会发言,每人3分钟,时间到了换下一个人。虽然可能话没说完,但至少每个人都有机会说。

关键参数:时间片大小

时间片 优点 缺点
太大(如100ms) 上下文切换少 接近FCFS,响应慢
太小(如1ms) 响应快,公平 切换开销大,CPU利用率低
适中(如10-20ms) 平衡 需要调优

💡 我的调优经验:

在分拣机里,我一般把时间片设为机械臂完成一次抓取动作的时间。这样每个包裹至少能完成一个完整动作,不会出现「抓了一半又放下」的尴尬情况。时间片设得太小,机械臂会像抽风一样来回抖动。

4.5 四种算法对比总结

算法 平均等待时间 公平性 实现难度 分拣推荐度
FCFS 好(按到达顺序) ★☆☆☆☆ ★★☆☆☆
SJF 差(长任务吃亏) ★★★☆☆ ★★★★☆
优先级 取决于优先级定义 差(可能饥饿) ★★☆☆☆ ★★★★★(有老化机制时)
RR 中等 最好 ★★☆☆☆ ★★★☆☆

我的最终建议:

没有银弹。我在实际项目中,经常是「混合调度」——用优先级做粗调度,用RR做细调度。比如VIP包裹优先,同优先级内用轮转。这样既保证了关键任务不耽误,又防止了低优先级饿死。

说白了,调度算法是门平衡的艺术。你追求公平,就牺牲效率;你追求效率,就可能不公平。选哪个?看你的业务场景说话。

下一章我会讲实时调度算法,那才是分拣机这种硬实时系统的真正考验。到时候再聊。