工作中调查问题时,涉及到了Linux进程调度机制的分析,这里总结一下。
Linux进程调度支持哪些调度策略?在Linux内核中可选择配置的吗?
在进程调度策略理论学习时有很多种,并且有些不兼容,需要多选一。
而Linux并不是多种策略可选择的。Linux使用固定的多种调度策略,内核选项中会有些调度策略参数的配置,并不是选择策略的选项。
Linux调度策略是基于进程的,每个进程有自己的调度策略。内核在进行进程调度时,多种调度策略的进程在一起,按调度策略和优先级统一进行进程调度。
Linux都有哪些调度策略
Linux每个进程有且只有一个调度策略。
使用chrt --max命令可查看系统中支持并可设置的调度策略。
SCHED_OTHER min/max priority : 0/0
SCHED_FIFO min/max priority : 1/99
SCHED_RR min/max priority : 1/99
SCHED_BATCH min/max priority : 0/0
SCHED_IDLE min/max priority : 0/0
SCHED_DEADLINE min/max priority : 0/0
-
SCHED_OTHER:即CFS(Completely Fair Scheduler)是Linux默认的进程调度策略。它旨在提供公平的CPU时间分配,以便每个进程都能在不超出其份额的情况下获得CPU时间。CFS使用红黑树数据结构来管理任务队列,以便按照任务的优先级动态分配CPU时间。
-
SCHED_FIFO、SCHED_RR、SCHED_DEADLINE:这三个是实时调度策略,这些策略用于实时任务,通常需要低延迟和确定性的CPU时间分配。SCHED_FIFO允许一个任务一直运行直到它主动释放CPU,而SCHED_RR为实时任务提供了时间片轮转的功能。SCHED_DEADLINE是截止时间调度策略用于确保特定任务在指定的截止时间内完成。
-
SCHED_BATCH :用于控制批处理任务的调度。它旨在为非交互式、低优先级的任务提供较低的CPU时间,并允许更高优先级的任务(如交互式任务)优先获得CPU时间。
-
SCHED_IDLE:是一种低优先级的轮询策略,用于处理系统空闲时的任务。这些任务只在CPU没有其他工作要执行时才会运行。
多种调度策略的优级
多种调度策略的进程在一起时,会按优先级进行调度。策略优先级从高到低如下:
实时优先级 | SCHED_DEADLINE | 按运行时间参数约束 |
SCHED_FIFO、SCHED_RR | 按策略优先级 | |
普通优先级 | SCHED_OTHER | 优先级与nice值有关 |
SCHED_BATCH | ||
低优先级 | SCHED_IDLE |
- 实时优先级:SCHED_DEADLINE策略由于按截止时间约束,因此可抢占SCHED_FIFO、SCHED_RR。SCHED_FIFO、SCHED_RR这两个通过priority值确定谁更优先。同优先级的SCHED_RR可交替执行,SCHED_FIFO不主动让出CPU。当优先级相同的SCHED_FIFO任务和SCHED_RR任务都存在时,SCHED_FIFO任务通常会优先执行,因为SCHED_FIFO没有时间片,一旦开始执行,它将一直运行,而SCHED_RR任务则进行轮转。它们都是固定优先级。
- 普通优先级:SCHED_OTHER即CFS(Completely Fair Scheduler)是Linux内核中的一种进程调度策略,其主要原理是提供公平的CPU时间分配,确保每个进程都能在不超出其份额的情况下获得CPU时间。CFS的设计目标是实现公平性和负载均衡,使得在多任务环境中每个进程都能获得公平的CPU时间份额。SCHED_BATCH与SCHED_OTHER相似,也是基于Nice值的动态优先级调度策略,通常被认为是CPU密集型进程,因此与SCHED_OTHER相比,SCHED_BATCH进程更倾向被调度器排到后面。
- 低优先级:SCHED_IDLE是一种低优先级的轮询策略,用于处理系统空闲时的任务。这些任务只在CPU没有其他工作要执行时才会运行。
进一步补充说明
- 实时优先级最高,当存在需要调度的实时优先级进程时,其它进程得不到调度。
- 默认情况下,大多数Linux进程使用CFS(Completely Fair Scheduler)策略,这是一种普通的时间分片调度策略。你可以通过调整
nice
值来精细调整进程的相对优先级。 - 如果系统中同时运行了 SCHED_FIFO、SCHED_RR 和 SCHED_DEADLINE 任务,并且它们都具有相同的最高优先级,SCHED_DEADLINE 任务将被认为是最高优先级的任务,因为它们必须满足更紧急的实时需求。系统会优先执行 SCHED_DEADLINE 任务,以确保它们在指定的截止时间内得到执行。
-
在 SCHED_RR策略下,所有使用该策略的进程被分配相同大小的时间片,通常以几毫秒为单位。这意味着在 SCHED_RR 中,所有进程得到的时间片大小相等,不受其优先级值的影响。
调度策略查看和设置
查看进程使用哪种调度策略
$ ps -e -o pid,cmd,pri,rtprio,class
PID CMD PRI RTPRIO CLS
1 /sbin/init splash 19 - TS
2 [kthreadd] 19 - TS
3 [rcu_gp] 39 - TS
4 [rcu_par_gp] 39 - TS
6 [kworker/0:0H-kblockd] 39 - TS
8 [mm_percpu_wq] 39 - TS
9 [ksoftirqd/0] 19 - TS
10 [rcu_sched] 19 - TS
11 [migration/0] 139 99 FF
12 [idle_inject/0] 90 50 FF
14 [cpuhp/0] 19 - TS
15 [cpuhp/1] 19 - TS
16 [idle_inject/1] 90 50 FF
17 [migration/1] 139 99 FF
18 [ksoftirqd/1] 19 - TS
20 [kworker/1:0H-kblockd] 39 - TS
21 [cpuhp/2] 19 - TS
22 [idle_inject/2] 90 50 FF
CLS列代表调度策略,TS对应SCHED_OTHER,FF对应SCHED_FIFO,RR对应SCHED_RR。
配置进程调度策略使用chrt
chrt [options] <priority> <command> [<arg>...]
chrt [options] --pid <priority> <pid>
坑:SCHED_RR调度策略的时间片
在 Linux 中,SCHED_RR(Round Robin)调度策略使用固定的时间片来调度实时进程。默认情况下,SCHED_RR 的时间片为100毫秒。
可通过proc查看和设置
$ cat /proc/sys/kernel/sched_rr_timeslice_ms
100
这个还是比较坑的,意味着实时性要求较高的进程,即使设置为FIFO或RR,也存在100ms以上得不到调度执行的情况,因此要考虑DEADLINE或降低时间片值。