Android 进程管理篇(四)-cpu限制

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 进程管理篇(四)-cpu限制相关的知识,希望对你有一定的参考价值。

参考技术A 梳理Process进程相关知识点,再继续补充点内容。

Linux系统中对进程的管理无非是从调度策略、优先级以及CPU限制三个角度进行配置与管理,那么android中主要是通过AMS来管理应用程序进程的,是不是也是从这三个方面进行管理的呢?答案是肯定的,那么本篇文章先来看看cpuset负载均衡在AMS中是如何应用的。

cpuset是Linux cgroup子系统,它为cgroup任务分配单独的CPU和内存。单独分配CPU即表明进程可调度cpu范围。cpu按不同的芯片,大小核数目和频率都有差别,大核频率高处理速度相对比小核快,而Android系统实际上还是响应优先于吞吐的交互型系统,因此Android AMS对进程管理于不同优先级的进程在调度cpu限制上会做有一些策略,以保证更好的交互响应。

还是回到AMS中与adj相关的有三个方法,这三个方法值得看一万遍,每一遍都会有新收获:

聚焦到computeOomAdjLocked方法,该方法主要是根据进程的四大组件状态决定当前进程的adj优先级。

以TOP_APP为例,这里ProcessRecord 的curSchedGroup属性对应的是cup调度组,而在后续applyOomAdjLocked中会执行Process的setProcessGroup方法。

调用Process的setProcessGroup方法

setProcessGroup是个native方法,并且这里分了若干类型的group,这里看top app优先级是最高的。接着jni到native

这里直接调用sched_policy.cpp的set_cpuset_policy,并传入对应的pid和SchedPolicy

这里主要就是通过policy对应具体的fd句柄,然后通过add_tid_to_cgroup()写cpuset对应节点。这里要注意,如果cpusets_enabled为false的话,会走set_sched_policy,这部分下篇会讲到。
看看对应的fd是什么:

那我们来看看对应节点是什么内容:

然后看看对应的cpuset配置:

显然,top app 满核随便跑,foreground跑在除了3这个核以外的所有核上, 而background只能跑在小核上。

不同芯片平台配置会有差别。

linux cgroup机制

参考技术A Cgroup是control group的缩写,是Linux内核提供的一种用于限制,记录,隔离进程组所使用物理资源(cpu,memory,io等)的机制。

cgroup提供了一系列的功能用于对Linux系统资源进行管理和限制,主要功能包括如下

1:限制进程组可以使用的资源数量,例如进程组对内存的使用上限。

2:进程组的执行优先级限制。

3:记录进程组所使用的资源数量,例如进程组所使用的cpu时间。

4:进程组隔离的能力。

在cgroup中有一些基本定义或概念

1:Task,理解为系统中需要被控制的进程。

2:Subsystem,可以被控制的资源系统,例如cpu,IO,内存等。

3:Cgroup,按照某种控制标准而划分而成的控制族。

4:hierarchy,Cgroup可以组织成树状结构,子节点继承父节点的控制标准。

在系统中创建新的hierarchy时,系统中的所有任务都属于该层级的默认cgroup(root group)的成员。

一个子系统只能附加到一个层级上。

一个层级可以附加多个子系统。

一个任务可以是cgroup的成员,但这些cgroup必须在不同的hierarchy中。

任务创建的子任务(进程),子进程自动成为父进程cgroup的成员。

关系图如下:

blkio -- 这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等等)。

cpu -- 这个子系统使用调度程序提供对 CPU 的 cgroup 任务访问。

cpuacct -- 这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。

cpuset -- 这个子系统为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点。

devices -- 这个子系统可允许或者拒绝 cgroup 中的任务访问设备。

freezer -- 这个子系统挂起或者恢复 cgroup 中的任务。

memory -- 这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。

net_cls -- 这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc)识别从具体 cgroup 中生成的数据包。

ns -- 名称空间子系统。

Linux系统中最多可以建12棵cgroup层级树(每棵树关联一个子系统),也可以最少建一颗cgroup层级树(关联所有12个控制子系统)

可以通过mount命令完成

1.挂载一颗和所有subsystem关联的cgroup树到/sys/fs/cgroup

mount -t cgroup

xxx /sys/fs/cgroup

2.挂载一颗和cpuset

subsystem关联的cgroup树到/sys/fs/cgroup/cpuset

mkdir

/sys/fs/cgroup/cpuset

mount -t cgroup -o

cpuset xxx /sys/fs/cgroup/cpuset

3.挂载一颗与cpu和cpuacct

subsystem关联的cgroup树到/sys/fs/cgroup/cpu,cpuacct

mkdir

/sys/fs/cgroup/cpu,cpuacct

mount -t cgroup -o

cpu,cpuacct xxx /sys/fs/cgroup/cpu,cpuacct

4.挂载一棵cgroup树,但不关联任何subsystem

mkdir

/sys/fs/cgroup/systemd

mount -t cgroup -o

none,name=systemd xxx /sys/fs/cgroup/system

通过mount可以查看到cgroup的默认挂载点

每个目录下,其中的文件描述了如何对资源进行限制。

在每个进程的/proc/$pid/cgroup文件中,描述了进程于cgroup的关系:

第一列描述cgroup的树ID(该ID可以在/proc/cgroups中一一对应);第二列描述绑定的所有子系统;第三列描述进程在cgroup中的路径。

当我们对某个任务需要进行限制时,不推荐直接在cgroup的各个子系统的root下修改配置,而是在对应的层级下建立单独的控制节点。

例如如下,在cpu目录下建立我们自己的子目录:

进入我们创建的子目录后,会看到系统已经创建好了资源控制文件,此时只需要修改这些配置文件满足要求既可以。

要控制我们的进程,只需要将进程ID添加到tasks配置文件中即可以。

以上是关于Android 进程管理篇(四)-cpu限制的主要内容,如果未能解决你的问题,请参考以下文章

操作系统笔记四 进程管理进程同步

讲清楚,说明白!进程管理

Android 进程与线程管理

Linux限制进程的CPU使用率

一个限制进程 CPU 使用率的解决方案

linux cgroup机制