实时线程优先级¶
实时线程优先级决定了线程在系统中的执行顺序,确保高优先级的线程在就绪时能够立即抢占低优先级线程的执行,从而保证关键路径的确定性延迟。
- 设置方法:在Linux系统中,可以使用pthread_setschedparam函数来设置线程的调度策略和优先级。
Linux内核的三种调度策略:
- SCHED_OTHER:分时调度策略,系统默认
- SCHED_FIFO:实时调度策略,先到先服务
- SCHED_RR:实时调度策略,时间片轮转
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
void* thread_function(void* arg) {
// 线程执行的代码
return NULL;
}
int main() {
pthread_t thread;
struct sched_param param;
int policy;
// 创建线程
if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {
perror("pthread_create");
return EXIT_FAILURE;
}
// 获取当前线程的调度策略和参数
if (pthread_getschedparam(pthread_self(), &policy, ¶m) != 0) {
perror("pthread_getschedparam");
return EXIT_FAILURE;
}
// 设置调度策略为SCHED_FIFO
policy = SCHED_FIFO;
// 设置线程优先级,取值范围为0到sched_get_priority_max(policy)
param.sched_priority = sched_get_priority_max(policy);
// 设置线程的调度策略和优先级
if (pthread_setschedparam(thread, policy, ¶m) != 0) {
perror("pthread_setschedparam");
return EXIT_FAILURE;
}
// 等待线程结束
if (pthread_join(thread, NULL) != 0) {
perror("pthread_join");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
// sched_setscheduler(pid_t pid, int policy, const struct sched_param *param)
// 这是对应调整进程优先级的函数
优先级反转及解决办法
在实时系统中,当高优先级线程因等待低优先级线程持有的资源(如互斥锁)而阻塞时,若中优先级线程抢占CPU,会导致:
- 低优先级线程无法及时释放资源
- 高优先级线程被“间接”延迟(本应最高优先级却最晚执行)
L(持锁)→ H(等待锁)→ M(抢占L)→ H持续阻塞
优先级继承(PTHREAD_PRIO_INHERIT)
- 高优先级线程H等待锁时,持有锁的低优先级线程L的优先级临时提升至H的优先级
- 提升后的L可立即抢占中优先级线程M,快速执行并释放锁
- L释放锁后,其优先级自动恢复原值
- 若存在多层等待(如L等待另一锁),系统会递归提升所有相关线程优先级
2.优先级天花板(PTHREAD_PRIO_PROTECT)
锁创建时预设天花板优先级,适用于已知资源依赖场景
命令: 使用 chrt (change real-time attributes) 命令,只针对进程调整优先级
# 将PID为 <pid> 的进程设置为 SCHED_FIFO 实时调度策略,优先级为最高的99
sudo chrt -f -p 99 <pid>
chrt 命令的基本语法是:
chrt [选项] <优先级> <命令> [命令参数...]
chrt [选项] -p <优先级> <PID>
<优先级>: 这是一个整数,表示调度优先级。其范围和含义取决于使用的调度策略。
<命令>: 你想要运行并设置其调度策略的命令及其参数。
<PID>: 你想要修改调度策略的现有进程的进程 ID。
chrt 支持多种实时调度策略,其中最常用的是:
--fifo (SCHED_FIFO):先到先服务 (First-In, First-Out)。具有相同优先级的进程会按照它们就绪的顺序执行。一旦一个 FIFO 进程开始运行,它会一直运行,直到它自己主动放弃 CPU、被阻塞(例如等待 I/O),或者被一个具有更高优先级的进程抢占。
--rr (SCHED_RR):轮转 (Round-Robin)。与 SCHED_FIFO 类似,但有一个时间片。当一个 RR 进程的时间片用完时,它会被移到就绪队列的末尾,让同等优先级的其他进程有机会运行。
--other (SCHED_OTHER):普通调度策略。这是系统的默认调度策略,使用 CFS (Completely Fair Scheduler)。
--batch (SCHED_BATCH):批处理调度策略。适用于不需要交互的批处理任务。
--idle (SCHED_IDLE):空闲调度策略。只在系统空闲时运行,优先级最低。
常用选项:
-p: 操作指定的 PID(进程 ID),而不是启动新命令。
-o: 设置 OTHER 调度策略(SCHED_OTHER)。
-f: 设置 FIFO 调度策略(SCHED_FIFO)。
-r: 设置 RR 调度策略(SCHED_RR)。
-b: 设置 BATCH 调度策略(SCHED_BATCH)。
-i: 设置 IDLE 调度策略(SCHED_IDLE)。
-g: 设置 GROUP 调度策略(SCHED_GROUP,不常用)。
-h: 设置 HIGH 调度策略(SCHED_HIGH,不常用)。
-a: 设置 AFR 调度策略(SCHED_AFR,不常用)。
-e: 设置 EDF 调度策略(SCHED_EDF,不常用)。
-d: 设置 DEADLINE 调度策略(SCHED_DEADLINE,不常用)。
-v: 显示 当前进程(或指定 PID)的调度策略和优先级。
--help: 显示帮助信息。
--version: 显示版本信息。