调度器—相关接口和命令行工具

一、CPU调度策略设置

1. 内核函数

int sched_setscheduler(struct task_struct *p, int policy, const struct sched_param *param)
衍生函数:
sched_setscheduler_nocheck

设置内核线程调度策略和优先级,优先级设置只对RT线程有效。

2. 系统调用

int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
int sched_getscheduler(pid_t pid);

若要设置为RT,需要root权限,此时RT优先级数值为99-param->sched_priority;若设置为CFS,param->sched_priority必须为0

3. Native函数

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); 

初始化attr,设置调度策略。设置为RT调度策略需要root权限,设置为CFS不需要。

4. 上层函数

native void setThreadScheduler(int tid, int policy, int priority) //Process.java

通过 android_util_Process.cpp 这个JNI文件中调用 sched_setscheduler 函数实现。

5. 命令行工具

chrt -f -p <pid> 15

将pid线程设置为RT(-f)线程,优先级比RT最低优先级提升15,为99-15=89

 

二、CPU调度优先级设置

1. 内核函数

void set_user_nice(struct task_struct *p, long nice)

和系统调用 nice 和 setpriority 对应。

2. 系统调用

int nice(int inc);

当前cfs线程优先级数值加inc,inc可正可负,对rt线程无效。

int getpriority(int which, id_t who);
int setpriority(int which, id_t who, int prio);

CFS线程在 nice=0(prio=120) 的基础上优先级数值加上 prio,对 RT 线程无效,RT线程使用 sched_setscheduler 设置优先级。优先级往低处设置不需要权限,优先级往高处设置需要相应的权限。参考《linux能力机制》

3. Native函数

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

初始化attr,设置调度优先级,若是RT策略,param->sched_priority取值1-99,设置后对应优先级数值为99-param->sched_priority,若是CFS策略,param->sched_priority必须为0.

int androidSetThreadPriority(pid_t tid, int pri) //android/system/core/libutils/Threads.cpp

4. 上层函数

native void setThreadPriority(int tid, int priority) //Process.java

通过 android_util_Process.cpp 这个JNI文件中调用setpriority函数实现。

5. 命令行工具

renice -n 2 -p <pid>

优先级数值加 2,也可以为负值。

 

三、绑核设置

1. 内核函数

void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
衍生函数:
set_cpus_allowed_common
set_cpus_allowed_ptr

2. 系统调用

int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask);
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);

cpusetsize 为 sizeof(cpu_set_t),可以 "man sched_setaffinity" 和 "$ man CPU_ZERO" 查看使用方法。看 /proc/pid/status 的 Cpus_allowed 查看设置成功情况。设置后此任务只能跑在设定的CPU上,即使被设置的CPU上和忙其它CPU很空闲,也不能被 balance 到其它CPU核上。

3. Native函数

待补充,目前还没发现有,但是Native函数可以直接使用系统调用。

4. 上层函数

待补充,目前还没发现有,但是自己可以在 Process.java 中进行封装后使用。

5. 命令行工具

taskset -p 0f <pid>

将线程pid绑定到 CPU0-CPU3,注意是 0f 而不是 0x0f.

6. cgroup 设置

cpuset分组,每个分组tasks文件里面的任务绑定到cpus文件指定的cpu上,可以通过下面方法查看

# find ./ -name cpus
# find ./ -name cpus | xargs cat

 

上一篇:学习笔记6


下一篇:安卓带百分比的进度条显示