# 2.2.3 核心概念 - 调度策略

上一节我们探讨了调度类的概念与代码实现，总体来说，调度类实际上是根据优先级对任务的一个粗略划分，调度器总是从高优先级的调度类开始寻找可执行的任务。但对于同一个调度类中的多个任务，如果他们的优先级相同的话，调度器如何决定该选哪一个呢？

这个问题通过调度策略（Sched Policy）来解决，不同调度类的调度策略实现如下：

* Stop 调度类 \
  Stop 调度类中只有一个任务可供执行，不需要定义任何调度策略。
* DL （Deadline）调度类\
  DL 只实现了一种调度策略：`SCHED_DEADLINE`, 用来调度优先级最高的用户任务。
* RT （Real-Time）\
  RT 提供了两种调度策略：`SCHED_FIFO` 与 `SCHED_RR,`对于使用 `SCHED_FIFO` 的任务，其会一直运行到主动放弃CPU; 而对于 `SCHED_RR` 的任务，如果多个任务的优先级相同，则大家会按照一定的时间配额来交替运行，即使一个任务一直处于可运行状态，在使用完自己的时间切片之后也会被抢占，然后被放入队列的尾巴等待下次机会。
* Fair CFS 实现了三种调度策略：
  1. `SCHED_NORMAL`: 被用于绝大多数用户进程
  2. `SCHED_BATCH`: 适用于没有用户交互行为的后台进程，用户对该类进程的响应时间要求不高，但对吞吐量要求较高，因此调度器会在完成所有 `SCHED_NORMAL` 的任务之后让该类任务不受打扰地跑上一段时间，这样能够最大限度地利用缓存。
  3. `SCHED_IDLE`: 这类调度策略被用于系统中优先级最低的任务，只有在没有任何其他任务可运行时，调度器才会将运行该类任务。
* Idle 同 Stop 一样，Idle 调度类也没有实现调度策略，注意不要将这类调度类与 CFS 中的 `SCHED_IDLE` 混淆。

调度策略的定义如下：

```
#define SCHED_NORMAL 0
#define SCHED_FIFO 1
#define SCHED_RR 2
#define SCHED_BATCH 3
/* SCHED_ISO: reserved but not implemented yet */
#define SCHED_IDLE 5
#define SCHED_DEADLINE 6
```

每个进程在创建时都会指定一个调度策略，从而自动归结到某个调度类下。

我们可以通过 `/proc/<pid>/sched` 中的内容来查看进程的调度策略，例如下面例子中，进程的调度策略为 `SCHED_NORMAL`:

```
grep 'policy' /proc/11742/sched
policy                                       :                    0
```
