Android与Linux系统中线程/进程优先级设定

关于Android、Linux内线程/进程优先级设定的一些笔记记录。
Views: 678
3 0
Read Time:1 Minute, 54 Second

在正文开始之前,我希望大家都能明白这样一个道理:系统运行时,在没有任何干预的情况下,各个进程获得CPU时间片的机会是均等的,也就是说各个进程获得的CPU时间是均等的。但是,有的进程相对于其他的进程会更重要一些,相对来说任务也可能更繁重一些,为了保证这些任务比较重、相对更重要的一些进程,就有了优先级这个概念。通过控制优先级,我们可以保证这些进程可以更多地占用CPU时间片,从而保证这些进程的运行。

实际上在我们的Unix/Linux系统内,是存在进程调度管理这个概念的。在Linux内,所有的进程大体上可以分为两个进程:即实时进程与非实时进程。实时进程其实是在实时操作系统中引申出来的概念,要求进程在较短的时间内响应,不会存在较长延时(中断、进程切换等)。而在Linux系统内,也是有实时进程这样一个概念的。为了表征这些实时进程,Linux内核为这些进程设定了一个优先级,范围为0~99,而非实时进程,其优先级取值范围为100 ~ 139。在我们使用诸如top命令或者ps命令查看进程时,我们会注意到两个值,一个是NI(nice),一个是PR/PRI(Priority),这两个值其实有一个对应关系,即:Priority=120+NICE

在我们的安卓系统中,我们内核中运行的程序优先级实际上就是在0~99这个优先级范围的。在这之上,是用户态的进程。而用户态的进程,就可以通过修改Nice值来影响其Priority值,进而影响到程序的优先级。其中,NICE值的取值范围是-20 ~ 19。在安卓系统中,修改进程的优先级实际上都是通过修改NICE值来实现的。

在了解以上背景后,我们来了解如何修改进程优先级。

修改Linux进程优先级

实际上在Linux系统内,是不区分进程与线程的。我们创建的线程或者进程,在Linux内都是同样去对待的。

获取当前线程调度设置项:需要#include <pthread.h>与#include <sched.h>两个头文件

int pthread_getschedparam(pthread_t thread, int *policy,struct sched_param *param);

设置当前线程调度设置项:

int pthread_setschedparam(pthread_t thread, int policy,const struct sched_param *param);

关于返回值:如果函数执行成功,返回值为0,反之则表明执行错误。使用strerror(errno)可以知悉具体的错误原因。

参数详解:

pthread_t thread:可以通过pthread_self(void)函数快捷获取pthread_t对象

policy:线程调度策略,大体上分为两类:一类是均衡调度模式,另一类是实时调度模式。

均衡调度模式:policy的取值如下

SCHED_OTHER:一般的Linux系统都是这种策略,标准的循环分时策略,均衡分配时间片

SCHED_BATCH:流处理分时调度策略

SCHED_IDLE:一般用于运行优先级较低的后台运行的任务调度

实时调度模式:会根据系统变化的状态进行调度策略的调整

SCHED_FIFO:先进先出策略,依据线程

SCHED_RR:是SCHED_FIFO的增强版策略,具有更好的实用性

param:指向结构体struct sched_param的指针,struct sched_param的内容如下:

struct sched_param {

    int sched_priority;     /* Scheduling priority */

};

其中priority意指具体的优先级。在均衡调度模式下,sched_priority的值只能为0值,而在policy为SCHED_FIFO和SCHED_RR时,其值取值范围为1~99,值越大优先级越高。

附上一段代码,了解一下如何使用这两个API:

//Get current thread policy
int policy = SCHED_RR;
sched_param sch_params;
sch_params.sched_priority = 20;
//拷贝构造,drawThread为函数循环体
std::thread drawThreadObj(&EvsRenderManager::drawThread, this);
ALOGI("pthread_setschedparam,policy->%d,priority->%d", policy, sch_params.sched_priority);
pthread_setschedparam(drawThreadObj.native_handle(), policy, &sch_params);
drawThreadObj.detach();
pthread_getschedparam(drawThreadObj.native_handle(), &policy, &sch_params);
//Get current policy corresponding prioriuty,normal range from 1~99
int priority_max = sched_get_priority_max(policy);
//Get current policy corresponding prioriuty,normal range from 1~99
int priority_min = sched_get_priority_min(policy);
ALOGI("drawThread priority is %d,max priority is %d,min priority is %d,policy is %d", sch_params.sched_priority,priority_max, priority_min, policy);

这里需要注意的是,在安卓系统内是没有实现 SCHED_FIFOSCHED_RR 这两个调度策略的,所以在安卓系统内修改进程优先级只能修改用户态的进程,且只能通过修改NICE值来进行修改。

修改Android进程优先级

使用setPriority与getPriority进行优先级的设置与检测,使用这两个API需要引用头文件<sys/resources.h>.

int setpriority(int which, id_t who, int nice);

int getpriority(int which, int who);

参数解读:

int which:指需要修改优先级的对象所属类别,这里支持三个类别,分别是:PRIO_PROCESS(代表某个具体进程)、PRIO_PGRP(代表某个进程组)、PRIO_USER(代表某个具体的USER,以user id进行区分)

id_t who:指在上述三种类别下的具体的值,如which为PRIO_PROCESS则who就是具体的进程id,如which为PRIO_PGRP,则who就是具体的进程组id,如which为PRIO_USER,则who就是具体的user id。

int nice:设定具体的进程nice值。这里与pthread_setschedparam不同的是,这里是通过nice值修改的优先级,而nice值的取值范围为-20~19。

以上就是这篇博文的全部内容啦,关于这部分的更多资料,可以参考谷歌官方文档以及Linux内核的文档,希望能够帮助到大家~

Happy
Happy
0 %
Sad
Sad
0 %
Excited
Excited
0 %
Sleepy
Sleepy
0 %
Angry
Angry
0 %
Surprise
Surprise
0 %
FranzKafka95
FranzKafka95

极客,文学爱好者。如果你也喜欢我,那你大可不必害羞。

Articles: 83

Leave a Reply

Your email address will not be published. Required fields are marked *

en_USEN