第1章 RTL线程优先级基础
1.1 实时线程库概念
实时线程库(Real-Time Thread Library,RTL)是一组封装了Linux内核实时调度策略的API集合,专门用于提供可预测、低延迟的线程响应能力。在Android SystemUI场景下,RTL用于确保用户交互线程(如触摸响应、动画更新)能够优先于后台任务获得CPU时间,避免因争抢调度导致界面卡顿。
与普通线程相比,RTL线程具有以下核心特性:
- 确定的调度顺序:依赖优先级抢占机制,高优先级线程可直接抢占低优先级线程,无需等待时间片轮转。
- 有限优先级范围:Linux实时优先级范围为0~99,数值越大优先级越高,普通线程的nice优先级范围100~139。
- 系统调用支持:通过
pthread_setschedparam、sched_setscheduler等接口设置实时调度策略和优先级。
关键概念:RTL线程必须与实时调度策略配合使用,仅设置高优先级而不指定SCHED_FIFO/SCHED_RR策略不会获得实时行为。
1.2 优先级范围与系统调用
Linux内核将线程优先级分为两大区域:实时区与普通区。SystemUI中的关键渲染、输入分发线程常运行在实时区。
| 区域 | 优先级范围 | 调度策略 | 典型用途 |
|---|---|---|---|
| 实时(RT) | 0 ~ 99 | SCHED_FIFO, SCHED_RR | SystemUI输入事件线程、vsync信号处理 |
| 普通(NORMAL) | 100 ~ 139 | SCHED_OTHER, SCHED_BATCH | 后台GC、日志压缩、非关键动画 |
| 空闲(IDLE) | —— | SCHED_IDLE | 低优先级后台扫描任务 |
设置实时优先级的核心系统调用及参数:
sched_setscheduler(pid, policy, param)– 设置调度策略与优先级结构体。pthread_setschedparam(thread, policy, param)– POSIX线程接口,适用于多线程编程。sched_get_priority_min/max(policy)– 查询指定策略下可用优先级范围。
权限限制:设置实时优先级需要CAP_SYS_NICE权限或进程具有root/ system身份。SystemUI进程通常以system用户运行,允许在99范围内调整,但部分低端设备可能受SELinux策略约束。
1.3 线程创建与属性设置
在Native代码中创建RTL线程时,必须通过线程属性对象(pthread_attr_t)或创建后动态设置。推荐在创建前设置调度策略和优先级,以避免线程运行在错误优先级下的风险。
标准实现流程:
- 初始化线程属性
pthread_attr_init(&attr) - 设置继承调度属性为显式设置
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) - 设置调度策略
pthread_attr_setschedpolicy(&attr, SCHED_FIFO) - 设置优先级(例如90)
pthread_attr_setschedparam(&attr, ¶m) - 创建线程
pthread_create(&thread, &attr, thread_func, arg) - 销毁属性
pthread_attr_destroy(&attr)
// 示例:创建一个SCHED_FIFO策略、优先级90的线程
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
void* rt_worker(void* arg) {
// 实时线程工作循环
while (1) {
// 处理SystemUI关键任务
}
return NULL;
}
int create_rt_thread(pthread_t* thread_id) {
pthread_attr_t attr;
struct sched_param param;
int ret;
ret = pthread_attr_init(&attr);
if (ret != 0) return ret;
// 不继承调用线程的调度属性
ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
if (ret != 0) goto err;
ret = pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
if (ret != 0) goto err;
param.sched_priority = 90;
ret = pthread_attr_setschedparam(&attr, ¶m);
if (ret != 0) goto err;
ret = pthread_create(thread_id, &attr, rt_worker, NULL);
err:
pthread_attr_destroy(&attr);
return ret;
}
调试检查:创建后可通过
/proc/[pid]/task/[tid]/stat 查看策略字段(第42字段,'F'表示SCHED_FIFO,'R'表示SCHED_RR,'O'表示SCHED_OTHER),确认策略生效。
常见错误:
- 忘记设置
PTHREAD_EXPLICIT_SCHED,导致线程继承父进程的普通调度策略,优先级设置被忽略。 - 优先级设置超出1~99范围(或超出
sched_get_priority_max返回值),导致pthread_attr_setschedparam返回EINVAL。 - 在未获取CAP_SYS_NICE权限的进程中调用上述接口,导致EPERM错误。