调度策略
在Linux上有如下调度策略,可以通过 chrt 进行查询/设置:
SCHED_FIFO:高优先级,先入先出,除非主动让出CPU,否则会一直占用CPU;
SCHED_RR:高优先级,基于时间片,轮转调度;
SCHED_OTHER:普通优先级;
SCHED_BATCH:普通优先级,针对"batch"类型的任务,切换没有SCHED_OTHER频繁;
SCHED_IDLE:普通优先级,适用于以低优先级运行的后台任务
查询调度策略
# 查询主进程调度策略与优先级chrt -p $pid# 查询线程调度策略与优先级chrt -p $tid# 查询进程下所有线程调度策略与优先级chrt -ap $pid
修改调度策略
# 修改调度策略chrt -o -p $prio $pid #SCHED_OTHER, $prio = 0chrt -f -p $prio $pid #SCHED_FIFO, $prio = [1,99]chrt -r -p $prio $pid #SCHED_RR, $prio = [1,99] chrt -b -p $prio $pid #SCHED_BATCH, $prio = 0chrt -i -p $prio $pid #SCHED_IDLE, $prio = 0# 获取每个调度策略所支持的min/max优先级范围chrt -m
优先级
在Linux中一共有139个优先级,从kernel的视角来看,范围为[1,139],数值越小,优先级越高。其中
[1,99]为实时优先级,对应SCHED_FIFO、SCHED_RR调度策略的实时进程;
[100,139]为普通优先级,对应SCHED_OTHER、SCHED_BATCH、SCHED_IDLE调度策略的普通进程,其默认优先级为120。
这里还有一个变量叫做 nice 值,范围[-20,19]。通过调整nice值可以间接调整优先级,nice值只对普通进程生效:
普通进程优先级 = 优先级 + nice
查询优先级
查询优先级的命令有很多,top、ps、chrt等等都可以,但是不同的工具、甚至不同的命令参数,显示的优先级范围、含义不同。
top
top可以直接看到PR(优先级)、NI(nice)。
PR范围:[-100,-2]&&[0,39],其中-100不会直接显示,而是以字符串"rt"的形式显示。PR数值越小,优先级越高。
NI范围:[-20,19]
[root@AOS ~]# topPID USERPR NI VIRT RES SHR S %CPU %MEMTIME+ COMMAND19442 ros 20 0 961708 81772 35616 S 0.3 0.5 0:16.54 node1 root20 0 119812 5444 3424 S 0.0 0.0 0:18.64 systemd2 root20 0 000 S 0.0 0.0 0:00.07 kthreadd3 root20 0 000 S 0.0 0.0 0:00.19 ksoftirqd/05 root 0 -20 000 S 0.0 0.0 0:00.00 kworker/0:0H9 rootrt 0 000 S 0.0 0.0 0:00.03 migration/0
ps
直接输入ps不会显示优先级信息,需要加入参数。ps具有多种风格的输入参数,不同的风格,显示的优先级范围、含义也不同。
风格1,ps elf
显示的PRI与top中的PR值一致,即[-100,-2]&&[0,39],数值越小,优先级越高;
风格2,ps -elf
显示的PRI=top.PR+60; 即[-40,58]&&[60,99],数值越小,优先级越高;
风格3,ps -elo pid,tid,rtprio,pri,ni,cmd
显示的PRI范围[1,139],数值越大,优先级越高,与内核视角的最终优先级刚好相反;
[root@AOS ~]# ps elfF UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND40 26399 26385 20 0 7028 3908 do_sel Ss+ pts/130:00 -bash USER=root LOGNAME=root ......40 25174 24247 20 0 7032 3808 do_wai Ss pts/110:00 -bash ASCEND_VECTOR_OBJ_PATH=......00 16200 15963 -2 - 5088 1480 -RN+ pts/17 70:53 \_ dd if=/dev/zero of=......[root@AOS ~]# ps -elfF S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTYTIME CMD4 S root 10 0 80 0 - 1156 do_wai 6月07 ? 00:00:01 init1 S root 20 0 80 0 -0 kthrea 6月07 ? 00:00:00 [kthreadd]1 I root 32 0 60 -20 -0 rescue 6月07 ? 00:00:00 [rcu_gp]1 I root 42 0 60 -20 -0 rescue 6月07 ? 00:00:00 [rcu_par_gp][root@AOS ~]# ps -eLo pid,tid,rtprio,pri,ni,cmdPID TID RTPRIO PRI NI CMD11- 19 0 init33- 39 -20 [rcu_gp]12 1299 139 - [migration/0]
chrt
chrt只能得到SCHED_FIFO、SCHED_RR实时优先级,范围[1,99]。数值越大,优先级越高。
实时优先级 = 100 - chrt优先级
[root@AOS ~]# chrt -p 27116pid 27116's current scheduling policy: SCHED_RRpid 27116's current scheduling priority: 10
设置优先级
对于普通进程,可以通过nice/renice调整nice值,从而影响普通进程的优先级。普通优先级 = 120 + nice;
对于实时进程,可以通过chrt直接调整优先级。实时优先级 = 100 - chrt优先级;
nice/renice
nice用于在启动时设置nice值,
$N为nice值,范围[-20,19],数值越小,优先级越高;
$proc_cmd为可执行程序;
nice $N $proc_cmd
renice用于程序已经启动后,再重新调整nice值,
$N为nice值,范围[-20,19],数值越小,优先级越高;
$pid为进程id;
renice $N -p $pid
renice可以对进程下的所有线程调整nice值,
$N为nice值,范围[-20,19],数值越小,优先级越高;
$pgrp为进程组id;
renice $N -g $pgrp
chrt
$policy为策略选项,可用-f/-r,分别为SCHED_FIFO/SCHED_RR;
$priority为优先级,范围[1,99],数值越大,优先级越高;
$pid为进程id;
chrt -$policy -p $priority $pid