Linux 进程与线程优先级配置(实时与普通策略)
面向应用开发与系统调试人员,系统说明 Linux 下进程/线程优先级的策略、可设置项、命令与API用法,以及常见实践与注意事项。
1. 调度策略与优先级概览
- 普通(CFS)策略:
SCHED_OTHER/SCHED_NORMAL、SCHED_BATCH、SCHED_IDLE- 不使用固定优先级数字;通过
nice(-20…19)影响权重与公平性(nice越小,权重越大)。
- 不使用固定优先级数字;通过
- 实时策略:
SCHED_FIFO、SCHED_RR、SCHED_DEADLINE- 使用数值优先级
rtprio(通常 1…99,数值越大优先级越高)。 FIFO:不分时间片,直到阻塞或主动让出;RR:固定时间片轮转;DEADLINE:以周期/运行时间/相对截止期控制(需 root 权限且更复杂)。
- 使用数值优先级
权限与限制:
- 设置实时策略/高优先级通常需要
CAP_SYS_NICE或 root 权限。 - 系统范围的限制由
ulimit -r、/etc/security/limits.conf(PAM limits)决定(最大 RT 优先级、允许的rtprio)。
2. 普通策略:nice 与优先级权重
- 命令行:
- 启动时设定:
nice -n -10 ./app - 运行中调整:
renice -n -5 -p <PID>(对指定进程)或renice -n -5 -u <USER>(对用户)。
- 启动时设定:
- 影响效果:
nice值越小(更负),权重越大,CFS 的vruntime增长更慢,更常被选中(详见 CFS 文档)。- 不是严格优先级排序;与系统负载、
sched_latency、min_granularity等参数共同影响。
3. 实时策略:FIFO/RR/DEADLINE 的配置
- chrt(命令行工具):
- 查看:
chrt -p <PID> - 设定策略与优先级:
chrt -f -p 90 <PID>(FIFO 90)chrt -r -p 80 <PID>(RR 80)- 启动时:
chrt -f 90 ./app、chrt -r 80 ./app
- 查看:
- sched_setattr(DEADLINE;需 root):
- 参数包括
runtime、period、deadline,可通过专用工具或自写程序调用sched_setattr()完成。
- 参数包括
- POSIX 线程 API(C):
- 设置线程策略与优先级:
#include <pthread.h> struct sched_param sp = { .sched_priority = 80 }; pthread_setschedparam(pthread_self(), SCHED_RR, &sp); - 创建时设定:
pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setschedpolicy(&attr, SCHED_FIFO); struct sched_param sp = { .sched_priority = 90 }; pthread_attr_setschedparam(&attr, &sp); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); pthread_create(&tid, &attr, thread_fn, NULL);
- 设置线程策略与优先级:
4. 权限与系统限制配置(PAM limits)
/etc/security/limits.conf示例:# 允许某用户将线程设置到 RT 优先级 90,最大LOCKED内存1GB user1 - rtprio 90 user1 - memlock 1048576 # 允许某组使用 RT 优先级上限 95 @rtgroup - rtprio 95- 生效条件:
- 依赖 PAM 的会话管理(例如通过登录、systemd 服务或 sshd 触发);确保
pam_limits.so在相应服务的 PAM 配置中。
- 依赖 PAM 的会话管理(例如通过登录、systemd 服务或 sshd 触发);确保
ulimit:ulimit -r显示最大实时优先级上限。
5. 典型实践与注意事项
- 谨慎使用 RT 优先级:
- 高 RT 优先级任务可能“压死”普通任务,导致系统不可响应;确保任务逻辑不阻塞、不做长时间 I/O。
- 将计算与I/O分离:
- RT线程处理小、确定性计算;普通线程执行 I/O(磁盘/网络)与复杂逻辑,避免RT线程阻塞。
- 绑定CPU与隔离:
- 使用
taskset或pthread_setaffinity_np()将 RT 线程绑定到特定核心;配合isolcpus/cpuset cgroup隔离提高确定性。
- 使用
- 与实时内核/调度参数:
- PREEMPT_RT 补丁与内核参数(
sched_rt_runtime_us)影响 RT 带宽与抢占;确认系统配置。
- PREEMPT_RT 补丁与内核参数(
- 与优先级反转:
- 使用优先级继承互斥锁(
pthread_mutexattr_setprotocol(..., PTHREAD_PRIO_INHERIT))避免优先级反转; - 对共享资源使用等待队列与限时锁(避免无限等待)。
- 使用优先级继承互斥锁(
6. 示例:线程设为 SCHED_FIFO 并绑定核心
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <unistd.h>
void* rt_worker(void* arg) {
while (1) {
// 确定性小计算
// ...
sched_yield(); // 主动让出
}
return NULL;
}
int main() {
pthread_attr_t attr; pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
struct sched_param sp = { .sched_priority = 90 };
pthread_attr_setschedparam(&attr, &sp);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_t tid; pthread_create(&tid, &attr, rt_worker, NULL);
// 绑定到CPU0
cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(0, &cpuset);
pthread_setaffinity_np(tid, sizeof(cpuset), &cpuset);
printf("RT thread started with FIFO/90 on CPU0\n");
pause();
return 0;
}
7. 参考与工具
man sched、man chrt、man nice、man renice、man pthread_setschedparam/etc/security/limits.conf、PAM 配置文件taskset、cpusetcgroup、isolcpus内核参数- sched
&spm=1001.2101.3001.5002&articleId=154476971&d=1&t=3&u=c3a831d678c64e3fa2b8d3b3e0296a77)
6683

被折叠的 条评论
为什么被折叠?



