Linux的优先级说明

一、背景

在工作中,不少同学对nice,priority,schedue策略,实时优先级,普通进程优先级的概念混淆,导致最后的代码可能引入bug,本文将统一进行说明,部分内容参考网络大佬的文章 ,文末标记引用来源。

二、优先级的设定 API及关键结构体

设置调度策略,在linux上,FIFO和RR都是RT 调度策略

#include 

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);

//policy: SCHED_FIFO, SCHED_RR, and SCHED_OTHER

设置线程优先级相关API

#include 

int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);

struct sched_param {
    int sched_priority;     /* Scheduling priority */
};

一个进程结构体中,优先级相关字段

struct task_struct {
	...
	int				prio;
	int				static_prio;
	int				normal_prio;
	unsigned int		        rt_priority;
	...
	unsigned int policy;
	...
};

这些优先级值的关系可以参考后面说明

三、Linux 优先级调度策略及优先级值的含义

不同调度策略的说明:

  1. SCHED_OTHER 分时调度策略 (normal thread
  2. SCHED_FIFO 实时调度策略:先到先得,一旦占用cpu则一直运行,直到有更高优先级任务到达或自己放弃 (RT thread
  3. SCHED_RR 实时调度策略:时间片轮转。当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平(RT thread

不同优先级关系的说明

Linux的优先级说明_第1张图片

详细描述可以参考文末《Linux调度器:进程优先级》

简单的说,先要区分RT 优先级和normal 优先级:

用户空间下

RT 优先级:1~99 (值越大,优先级越高)

normal 优先级: nice 值从 -20(优先级最高) ~ 19(优先级最低) ,nice值是越小优先级越高,默认为0

内核空间中(会对normal和rt 线程优先级 nice值做归一化,对内核来讲都是一个个的task_struct,归一化有利于后面调度策略的计算和选择)

从用户空间的rt优先级值和normal线程的nice值看到,它们的定义似乎是相反的,一个越大代表优先级越高,一个越小优先级越高,怎么归一化呢,实际上内核中是用99 - rt 值进行了反转

normal_priority RT线程优先级:0~99 (注意这里的0~99 和用户空间真实设定的值是相反的关系,用户空间设置rt优先级99,这里就是0)

normal_priority normal线程优先级:100~139 (nice值为 -20,代表这里的100)

nice值 priority 内核空间归一化的优先级
普通线程 -20~19 0 100~139
RT线程 / 1~99 98~0 (图实际有点小错误,99 不可到达)

四、工具显示的优先级差异

常见的查看优先级方法:

top

ps -el

atop -s

实验一、一个普通进程下不同工具的显示结果

利用工具chrt来设置调度策略及优先级,如:sudo chrt -r 50 ./hello ---- 设置 SCHED_RR,优先级为50

top

ps -el

F S   UID     PID    PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 R     0    5352    5351 95   9   - -   660 -      pts/2    00:18:38 hello

atop -s

实验二、一个RT进程不同工具的显示结果

利用nice来调整,如:sudo nice -n 5 ./hello ---设置普通进程 nice值为5

top

ps -el

F S   UID     PID    PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 R     0    6917    6916 99  85   5 -   660 -      pts/2    00:00:07 hello

atop -s

这些工具显示同一个进程的优先级数值却大不相同,这些值怎么和API 设置的值对应起来?这些值只是工具计算的方式不同导致的,其中和当前内核/userspace设置比较匹配的是atop;

top 在普通进程default PR值是20, 根据nice值做调整,PR取值范围在0~39, 但是在表示rt thread时,全部都是负值, 为-1-rt, 从 -2 ~ -99(这里你会有疑问,rt的值是1~99,还有一个-100怎么没有?实际当rt=99时,这里的PR会显示rt)

ps -el 它的PRI 值取值范围是 -40 ~99 (和内核归一化的值0~139 有-40的差值), 它的值实际和内核归一化的含义一致,只是有-40 的差值;

atop -s 的取值 PRI就是内核归一化的值, RTPR 在线程为rt线程时,显示为用户api设置的值,当为normal线程时为0;

五、总结

linux 下不同工具显示的优先级数值,不同的展示方式给开发者带来了困扰,再叠加用户空间设置优先级值,调度策略,以及内核侧又重新进行了归一化操作,部分工具显示的内核归一化的值,导致这些概念数值困扰了开发者,这里将工具的差异做了一个总结:

工具 PR NI PRI NICE RTPR POLI
RT线程 top -1 - rt 0无意义 / / / /
normal top 20 + nice值 nice值 / / / /
RT线程 ps -el / 无意义 99 - rt - 40 / / /
normal ps -el / nice值 120 + nice -40 / / /
RT线程 atop -s / / 99-rt rt rr/fifo
normal atop -s / / 120+nice nice值 0 normal

上面表中的rt值和nice值均为用户空间设置的值

参考资源:

Linux调度器:进程优先级

articles/20230802-linux-sched-api.md · aosp-riscv/working-group - Gitee.com

https://mp.weixin.qq.com/s/44Gamu17Vkl77OGV2KkRmQ

你可能感兴趣的:(linux基础知识及工具,linux,进程优先级,linux,kernel)