# Linux 进程调度策略详细总结


# Linux进程调度策略详细总结
Linux进程调度是内核核心子系统，负责决定CPU资源的分配顺序与时长，通过**分层调度器架构**和**多类调度策略**，兼顾通用场景的公平性、实时场景的低延迟与批处理场景的吞吐量。本文从核心基础、调度策略详解、对比、实践接口与注意事项五个维度，完整梳理Linux进程调度体系。

## 一、Linux调度体系核心基础
### 1. 调度器演进与架构
Linux内核调度器经历了三代核心演进，当前主流分为两大稳定分支：
| 调度器 | 内核版本 | 核心定位 | 核心思想 |
|--------|----------|----------|----------|
| O(1)调度器 | 2.6早期~2.6.22 | 传统通用调度 | 固定优先级哈希桶，O(1)时间复杂度调度，对交互式进程不友好 |
| CFS完全公平调度器 | 2.6.23~6.5 | 默认通用进程调度 | 虚拟运行时间vruntime为核心，红黑树管理进程，保证CPU时间按权重公平分配 |
| EEVDF调度器 | 6.6+（6.12后完全替代CFS） | 新一代默认通用调度 | 最早可用虚拟截止时间优先，解决CFS延迟不稳定问题，兼顾公平性与低延迟，用户态接口完全兼容CFS |

同时，内核为不同调度策略提供独立的调度类，优先级从高到低为：**Deadline调度类 > RT实时调度类 > Fair公平调度类**，调度器总是优先从高优先级调度类中选取可运行进程。

### 2. 进程优先级体系
Linux将进程分为**实时进程**与**普通（非实时）进程**，采用两套独立的优先级体系，优先级数值规则完全不同：
1.  **实时优先级（rt_priority）**
    - 用户态可设置范围：**1~99**，数值越大，优先级越高（99为最高实时优先级）
    - 适用范围：SCHED_FIFO、SCHED_RR调度策略的进程
    - 核心规则：所有实时进程优先级**绝对高于**所有普通进程，高优先级实时进程可直接抢占低优先级实时/普通进程
2.  **普通进程优先级（nice值）**
    - 可设置范围：**-20~+19**，默认值为0，数值越小，优先级越高（-20为最高普通优先级）
    - 适用范围：SCHED_OTHER、SCHED_BATCH、SCHED_IDLE调度策略的进程
    - 核心规则：nice值通过权重影响CPU时间分配，nice值越低，权重越高，获得的CPU时间份额越多；普通用户仅能调高nice值（降低优先级），root用户可任意调整
3.  **最高优先级特例**：SCHED_DEADLINE调度策略的进程，优先级**高于所有传统实时进程**，不受1~99实时优先级限制。

## 二、Linux核心调度策略全解析
Linux内核共支持6种核心调度策略，分为**实时调度策略**、**普通/公平调度策略**、**截止时间调度策略**三大类，以下为每类策略的详细原理与特性。

### （一）实时调度策略（RT调度类）
专为对响应延迟有严格要求的实时任务设计，遵循**绝对优先级抢占**原则，只要有可运行的高优先级实时进程，低优先级进程就无法获得CPU。包含SCHED_FIFO和SCHED_RR两种核心策略。

#### 1. SCHED_FIFO：先进先出实时调度
- **核心机制**：无固定时间片，进程一旦获得CPU，会持续运行直到**主动放弃CPU**（sleep、IO阻塞、调用sched_yield()）、**被更高优先级实时进程抢占**或进程终止。
- **调度规则**：
  - 高优先级抢占：仅更高优先级的实时进程可抢占当前运行的SCHED_FIFO进程；
  - 同优先级排队：同优先级的FIFO进程按入队顺序执行，前一个进程不释放CPU，后续进程无法运行；
  - 普通进程完全被压制：只要有可运行的FIFO进程，普通进程无法被调度。
- **适用场景**：对延迟要求极高、执行时间短且确定的硬实时任务，如工业控制、传感器数据采集、航空航天控制系统、关键中断兜底任务。
- **风险提示**：高优先级FIFO进程若陷入死循环且不主动释放CPU，会独占对应CPU核，导致低优先级进程（包括系统内核线程、sshd等管理进程）完全饿死，最终只能重启系统。

#### 2. SCHED_RR：时间片轮转实时调度
- **核心机制**：SCHED_FIFO的增强版，保留优先级抢占规则，为同优先级进程增加**固定时间片**限制。进程时间片耗尽后，会被放到同优先级实时队列的队尾，调度同优先级的下一个进程。
- **调度规则**：
  - 高优先级抢占规则与SCHED_FIFO完全一致；
  - 同优先级公平轮转：同优先级的RR进程按时间片轮流占用CPU，避免单个进程独占CPU；
  - 时间片配置：默认时间片可通过`/proc/sys/kernel/sched_rr_timeslice_ms`配置，默认值通常为100ms，可通过`sched_rr_get_interval()`系统调用获取进程时间片；
  - 与FIFO兼容：同优先级下，SCHED_FIFO进程若不释放CPU，SCHED_RR进程无法抢占。
- **适用场景**：同优先级的多实时任务，需要公平分配CPU时间，避免单任务饿死，如多通道实时数据处理、多路音视频实时流处理。

### （二）普通/公平调度策略（Fair调度类）
Linux系统默认的调度策略，绝大多数用户态进程都使用此类策略，底层由CFS/EEVDF调度器驱动，核心目标是保证CPU资源的公平分配，兼顾交互式进程的响应性与批处理任务的吞吐量。包含SCHED_OTHER、SCHED_BATCH、SCHED_IDLE三种策略。

#### 1. SCHED_OTHER/SCHED_NORMAL：默认通用调度
- **核心机制**：Linux系统**默认调度策略**，所有未显式设置调度策略的进程均使用该策略。
  - CFS实现：以**虚拟运行时间vruntime**为核心，vruntime = 实际运行时间 / 进程权重（由nice值决定）；调度器总是选择vruntime最小的进程执行，用红黑树管理进程，保证O(logN)的查找效率。
  - EEVDF实现：以虚拟截止时间为核心，筛选符合条件的进程后，选择截止时间最早的进程执行，优化了高并发下的调度延迟与公平性，用户态使用方式完全兼容CFS。
- **调度规则**：
  - 按nice值权重分配CPU时间：nice值越低，权重越高，相同时间内获得的CPU时间越多；
  - 动态时间片：无固定时间片，时间片长度根据系统负载、进程数量动态调整，保证调度延迟目标；
  - 内核态抢占：用户态进程无法直接抢占，仅内核态可在中断返回、进程状态变化时触发抢占。
- **适用场景**：绝大多数通用场景，包括桌面应用、后台服务、编译任务、网络服务、数据库等，是Linux最通用的调度策略。

#### 2. SCHED_BATCH：批处理调度
- **核心机制**：基于CFS/EEVDF调度器，专为CPU密集型批处理任务优化。调度器将其标记为非交互式进程，**减少抢占频率**，允许进程更长时间占用CPU，提高CPU缓存命中率，降低上下文切换开销。
- **调度规则**：
  - 即使nice值与SCHED_OTHER进程相同，也会被降低调度优先级，减少被交互式进程抢占的概率；
  - 不进行唤醒抢占优化，避免频繁打断批处理任务；
  - 优先级仍高于SCHED_IDLE，低于实时进程。
- **适用场景**：CPU密集型、无交互需求的后台批处理任务，如科学计算、大数据离线处理、代码全量编译、视频渲染、数据备份等，追求高吞吐量而非低延迟。

#### 3. SCHED_IDLE：空闲调度
- **核心机制**：Linux系统优先级最低的调度策略，仅当对应CPU核上**没有任何其他可运行的进程**时，才会调度该策略的进程。
- **调度规则**：
  - 进程权重极低，vruntime增长极快，只要有其他普通进程可运行，就会被抢占；
  - 即使是nice值为+19的SCHED_OTHER进程，优先级也远高于SCHED_IDLE进程。
- **适用场景**：系统极低优先级的闲置后台任务，仅在系统空闲时执行，如分布式闲置算力计算、非紧急的系统垃圾清理、日志归档、闲时系统维护任务。

### （三）截止时间调度策略（Deadline调度类）
#### SCHED_DEADLINE：截止时间实时调度
Linux 3.14内核引入，专为有严格时间约束的硬实时任务设计，是Linux中优先级最高的调度策略，基于**EDF（最早截止时间优先）+ CBS（恒定带宽服务器）** 算法实现，解决了传统实时调度无法保证任务截止期的问题。

- **核心三参数**：调度前必须为进程配置三个核心参数，单位为微秒：
  1.  **Runtime（运行时间）**：每个周期内，任务需要的最大CPU执行时间；
  2.  **Period（周期）**：任务的执行周期，即每隔多久触发一次任务；
  3.  **Deadline（相对截止时间）**：每个周期内，任务必须完成的最晚时间，通常小于等于Period。
- **核心调度机制**：
  1.  **EDF算法**：调度器维护按绝对截止时间排序的红黑树，每次始终选择**截止时间最早**的进程执行，若新进程的截止时间早于当前运行进程，会立即触发抢占；
  2.  **CBS带宽控制**：为每个进程分配固定的CPU带宽（Runtime/Period），进程运行时消耗预算，预算耗尽后会被节流，直到下一个周期刷新预算，避免任务超支影响其他进程；
  3.  **准入控制**：内核会校验所有SCHED_DEADLINE进程的总带宽，默认不超过CPU核的95%（预留5%给普通进程），过载时拒绝新任务接入，保证已有任务的截止期可满足。
- **适用场景**：有严格确定性延迟要求的硬实时任务，如自动驾驶实时感知、工业机器人运动控制、专业音视频帧处理、医疗设备实时控制等，必须在固定周期内完成固定计算量。
- **权限要求**：必须使用root用户或具备CAP_SYS_NICE权限的进程才能配置。

## 三、Linux调度策略核心对比表
| 调度策略 | 类型 | 所属调度类 | 优先级范围 | 核心机制 | 时间片 | 核心抢占规则 | 典型适用场景 |
|----------|------|------------|------------|----------|--------|--------------|--------------|
| SCHED_DEADLINE | 硬实时 | Deadline | 系统最高 | EDF+CBS+准入控制，按截止时间调度 | 动态预算 | 截止时间更早的进程可抢占，优先级高于所有实时进程 | 自动驾驶、工业机器人、硬实时帧处理 |
| SCHED_FIFO | 实时 | RT | 1~99（数值越大优先级越高） | 先进先出，无时间片，直到主动释放或被高优先级抢占 | 无 | 仅更高优先级实时进程可抢占，同优先级无法抢占 | 工业控制、低延迟关键任务、传感器采集 |
| SCHED_RR | 实时 | RT | 1~99（数值越大优先级越高） | 同优先级时间片轮转，高优先级抢占规则同FIFO | 固定可配置 | 高优先级可抢占，同优先级时间片耗尽后让出CPU | 多通道实时处理、同优先级多实时任务 |
| SCHED_OTHER/NORMAL | 普通 | Fair | nice -20~+19（数值越小优先级越高） | CFS/EEVDF，按权重公平分配CPU时间 | 动态调整 | 内核态可抢占，按虚拟时间/截止时间调度，无用户态抢占 | 桌面应用、后台服务、网络服务、通用场景 |
| SCHED_BATCH | 普通 | Fair | nice -20~+19 | 优化CPU密集型任务，减少抢占，提升缓存命中率 | 动态长周期 | 降低抢占频率，减少被交互进程打断 | 科学计算、编译、渲染、离线批处理 |
| SCHED_IDLE | 普通 | Fair | 系统最低 | 仅CPU无其他可运行进程时调度 | 动态 | 任何其他进程都可抢占 | 闲时系统维护、闲置算力任务、非紧急清理 |

## 四、调度策略相关系统调用与工具
### 1. 核心系统调用
| 系统调用 | 核心功能 |
|----------|----------|
| `sched_setscheduler()` | 设置进程的调度策略、优先级、实时参数 |
| `sched_getscheduler()` | 获取进程当前使用的调度策略 |
| `sched_setparam()`/`sched_getparam()` | 设置/获取进程的调度优先级参数 |
| `sched_setattr()`/`sched_getattr()` | 新一代调度属性设置接口，支持SCHED_DEADLINE三参数配置 |
| `nice()` | 调整当前进程的nice值 |
| `setpriority()`/`getpriority()` | 设置/获取进程、进程组、用户的nice优先级 |
| `sched_yield()` | 主动放弃CPU，让出调度权 |
| `sched_setaffinity()`/`sched_getaffinity()` | 设置/获取进程的CPU亲和性，绑定进程到指定CPU核 |
| `sched_rr_get_interval()` | 获取SCHED_RR进程的时间片长度 |

### 2. 用户态常用工具
- `chrt`：查看/设置进程的调度策略与实时优先级，支持所有调度策略配置；
- `nice`/`renice`：启动进程时设置nice值，或调整运行中进程的nice值；
- `top`/`htop`：查看进程的调度策略、PR优先级、NI值、CPU占用等信息；
- `taskset`：设置进程的CPU亲和性，绑定进程到指定CPU核。

## 五、生产环境核心注意事项
1.  **实时进程风险管控**：SCHED_FIFO/SCHED_RR高优先级进程必须保证能主动释放CPU，禁止死循环无阻塞逻辑；建议绑定到隔离的CPU核，避免影响系统核心进程。
2.  **权限控制**：所有实时调度策略、nice负值设置、SCHED_DEADLINE配置，都需要root权限或CAP_SYS_NICE能力，禁止给普通业务进程开放该权限。
3.  **SCHED_DEADLINE配置规范**：三参数配置需留足冗余，Runtime需大于任务最大执行时间，总带宽不超过CPU核的80%，避免过载导致截止期违约。
4.  **CPU隔离与亲和性**：实时任务建议通过`isolcpus`内核参数隔离CPU核，避免内核负载均衡带来的调度延迟，配合CPU亲和性绑定，提升调度确定性。
5.  **普通进程调优原则**：CPU密集型任务优先使用SCHED_BATCH，降低上下文切换；闲置任务使用SCHED_IDLE，避免影响业务进程；非必要不调整nice负值。


