Linux 任务调度策略
🌟 概述
Linux 内核以线程(任务)为单位进行调度,支持 SCHED_FIFO 和 SCHED_RR(实时调度)以及 SCHED_OTHER(基于 CFS,非实时调度)。
🔍 调度策略
1. SCHED_FIFO(先进先出)
- 机制:按优先级和到达顺序运行,无时间片,直到阻塞、被抢占或终止。
- 特点:优先级 1-99,低延迟,适合硬实时任务。
- 场景:音频处理、工业控制。
2. SCHED_RR(轮转法)
- 机制:同优先级线程按时间片轮转,用尽后重新排队。
- 特点:优先级 1-99,平衡实时性和公平性。
- 场景:视频流、实时通信。
3. SCHED_OTHER(CFS)
- 机制:基于 vruntime 公平调度,动态分配 CPU 时间。
- 特点:nice 值 -20 到 19,适合非实时任务。
- 场景:Web 服务器、桌面应用。
📊 调度策略对比
特性 | SCHED_FIFO | SCHED_RR | SCHED_OTHER (CFS) |
---|---|---|---|
类型 | 实时 | 实时 | 非实时 |
调度单位 | 线程 | 线程 | 线程 |
调度方式 | 先进先出 | 时间片轮转 | vruntime 公平分配 |
时间片 | 无 | 固定(10-100ms) | 动态调整 |
优先级 | 1-99 | 1-99 | nice 值 -20 到 19 |
场景 | 硬实时(如音频) | 软实时(如多媒体) | 通用任务(如服务器) |
权限 | 需 root | 需 root | 无需权限 |
风险 | 低优先级线程可能被饿死 | 时间片切换增加延迟 | 不适合实时任务 |
🛠️ 主要 API
sched_setscheduler(pid, policy, param)
:设置线程策略和优先级。sched_getscheduler(pid)
:查询线程策略。sched_setparam(pid, param)
:设置优先级(SCHED_OTHER 忽略)。sched_yield()
:让出 CPU。- 结构:
struct sched_param { int sched_priority; };
。
⚠️ 注意
- SCHED_FIFO/RR 需 root 权限,优先级高于 SCHED_OTHER。
- SCHED_OTHER 使用 nice 值调整优先级。
- SCHED_FIFO 高优先级线程可能导致低优先级线程被饿死。
✅ 优点
- SCHED_FIFO:低延迟,硬实时。
- SCHED_RR:实时与公平平衡。
- SCHED_OTHER:公平,适合通用任务。
🚫 局限性
- SCHED_FIFO:可能饿死低优先级线程。
- SCHED_RR:切换开销。
- SCHED_OTHER:不适合实时。