线程调度策略
2025/9/11...大约 2 分钟
Linux内核使用完全公平调度器(CFS, Completely Fair Scheduler)作为默认调度器,同时还支持实时调度策略。Linux将线程和进程统一看待,都称为任务(task)。
下面是Linux调度策略的整体分类:
| 策略分类 | 策略名主要特点 | 主要特点 | 适用场景 |
|---|---|---|---|
| 普通调度 | SCHED_NORMAL | 默认调度,完全公平调度器CFS | 适合普通应用 |
SCHED_BATCH | 批处理任务,减少调度频率 | 适合CPU密集型 | |
SCHED_IDLE | 仅在系统空闲时运行 | 适合后台/低优先级任务 | |
| 实时调度 | SCHED_FIFO | 实时,先进先出,优先级高 | 适合硬实时任务(工业控制,医疗设备等) |
SCHED_RR | 实时,时间片轮转 | 适合软实时/多媒体任务(音频播放,视频解码,直播等) | |
SCHED_DEADLINE | 实时,基于截止时间 | 适合周期性/严格实时任务(音频采集/处理, 高频交易系统等) |
CFS调度器
CFS是Linux默认调度器,它的优先级策略是控制任务的执行时间,优先级更高的,真正可以使用的CPU时间就更多。但是值得注意的是,在Linux中,使用的是vruntime (虚拟运行时间)的增长速度来反映任务的优先级,优先级高的vruntime的增长速度越慢,对应的任务的实际可使用的CPU时间越多。
该策略下,任务就绪队列使用红黑树维护,按vruntime进行排序,vruntime越小,优先级越高。
整体调度策略
Linux调度器会优先调度实时线程,再调度普通线程。调度优先级大致如下(由上到下,优先级逐渐降低):
SCHED_DEADLINESCHED_FIFOSCHED_RRSCHED_OTHER(SCHED_NORMAL)SCHED_BATCHSCHED_IDLE
需要记住一点,实时调度策略的任务总是高于普通任务的,核心原则如下:
- 高优先级策略的线程,只有在没有更高优先级线程可运行时,才会让出
CPU; - 低优先级策略的线程,只有在高优先级线程都阻塞/睡眠/结束时,才有机会运行;
实时线程 vs 普通线程
- 实时线程(
SCHED_FIFO、SCHED_RR、SCHED_DEADLINE)会抢占普通线程(SCHED_OTHER、SCHED_BATCH、SCHED_IDLE)的CPU时间; - 只要有可运行的实时线程,普通线程就无法获得
CPU;
不同实时策略之间
SCHED_DEADLINE优先级最高,调度器会优先满足其截止时间需求;SCHED_FIFO和SCHED_RR按优先级数字(1~99)排序,数字越大优先级越高;- 同优先级下,
SCHED_FIFO按先来先服务,SCHED_RR按时间片轮转;
修改优先级的方式
linux shell下,可以通过nice/renice/chrt等命令修改nice值。设置或修改实时任务优先级任务需要root权限。