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限制的主要内容,如果未能解决你的问题,请参考以下文章