Android进程线程之cgroups的使用详解

原文地址:http://www.maiziedu.com/article/5718/

    Android开发中,很多开发者可能对cgroups并不是很了解,甚至有些初学者对cgroups是陌生的,今天小编就和大家分享cgroups到底是什么,又有什么用?

 

Cgroups是什么?

 其实cgroups是Linux内核的一个功能,用来限制、控制与分离一个进程组群的资源(如CPU、内存、磁盘输入输出等)

 

Cgroups的使用

 了解了cgroups是什么以后,接下来我们将通过例子,为大家展示其具体用法。以Fedora这个Linux发行版为例,在开发中怎样使用cgroups限制进程的CPU使用率呢?


1.使用一个死循环的Python脚本用来消耗CPU,并将文件命名为loop.py,。

#!/usr/bin/env python

# coding=utf-8

i = 0

while True:

    i = i + 1

 

执行脚本python loop.py,使用top查看该进程的CPU使用情况,CPU使用率接近100%

使用top -d 1,然后再按下1.可以看到如下结果,进程9971在CPU的占用率接近100%

 

2.修改配置,利用cgroups将该进程的CPU使用率降低到10%

输入sudo mount -t cgroup查看当前系统的cgroups:

sudo mount -t cgroup
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu type cgroup (rw,relatime,cpu)
cgroup on /sys/fs/cgroup/cpuacct type cgroup (rw,relatime,cpuacct)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,relatime,blkio)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,relatime,freezer)
cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,relatime,net_cls)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,relatime,perf_event)
cgroup on /sys/fs/cgroup/net_prio type cgroup (rw,relatime,net_prio)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,relatime,hugetlb)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,relatime,pids)
systemd on /sys/fs/cgroup/systemd type cgroup (rw,noexec,nosuid,nodev,none,name=systemd)


2.1 创建一个新的cgroup,控制CPU使用率:

 cd /sys/fs/cgroup/cpu

sudo mkdir cpu_test

接下来查看刚刚创建的cpu_test

 17:04:54-androidyue/sys/fs/cgroup/cpu$ls cpu_test/

cgroup.clone_children  cpu.cfs_period_us  cpu.shares  notify_on_release
cgroup.procs           cpu.cfs_quota_us   cpu.stat    tasks

 

完成这一目标修改涉及到的文件有:

cpu.cfs_period_us 设置该cgroup请求到CPU资源分配的周期,单位为微秒(这里使用us代替微秒单位µs)。

cpu.cfs_quota_us 设置cgroup组内的进程在一次CPU分配周期(即cpu.cfs_period_us指定的值)内可以执行的时间。

 

2.2 如果要设置该cpu_test组内的cpu使用率为10%,需要做以下修改:

echo 1000000 > cpu.cfs_period_us

echo 100000 > cpu.cfs_quota_us

注意:上述修改需要使用root身份登陆,即sudo –i,下面的将进程加入cgroup同样需要root身份。

 

2.3 将上面的进程ID 写入到cpu_test下的tasks文件中,并查看tasks验证是否加入成功

 sudo echo 11950> tasks

cat tasks

11950


3. 再次查看进程id11950CPU使用率,已成功降低到10%左右。

 

cgroupsAndroid中的应用

在Android中也存在cgroups,但涉及到CPU的目前只有两个,一个是apps,路径为/dev/cpuctl/apps。另一个是bg_non_interactive,路径为/dev/cpuctl/apps/bg_non_interactive


在Android N内核中,/dev/cpuctl的目录内容变成:

bg_non_interactive    cgroup.sane_behavior cpu.shares        tasks 
cgroup.clone_children cpu.rt_period_us     notify_on_release 
cgroup.procs          cpu.rt_runtime_us    release_agent 

在此目录下,有一个bg_non_interactive目录:

cgroup.clone_children cpu.rt_period_us  cpu.shares        tasks 
cgroup.procs          cpu.rt_runtime_us notify_on_release 

 

dev/cpuctl/                                  --位于前台的app

dev/cpuctl/bg_non_interactive     --进入后台的app


1cpu.share

cpu.share文件中保存了整数值,用来设置cgroup分组任务获得CPU时间的相对值。举例来说,cgroup Acgroup Bcpu.share值都是1024,那么cgroup A cgroup B中的任务分配到的CPU时间相同,如果cgroup Ccpu.share512,那么cgroup C中的任务获得的CPU时间是AB的一半。

 

cpu.share 值为1024

hikey:/dev/cpuctl # cat cpu.shares                                             
1024

 

bg_non_interactive下的cpu_share值为52

hikey:/dev/cpuctl/bg_non_interactive # cat cpu.shares                          
52

 

从上面的数据可以看出,默认分组与bg_non_interactive分组cpu.share值相比接近于20:1。由于Android中只有这两个cgroup,也就是说默认分组中的应用可以利用95%CPU,而处于bg_non_interactive分组中的应用则只能获得5%CPU利用率。

52/(1024+52)=4.8%

 

2cpu.rt_period_uscpu.rt_runtime_us

cpu.rt_period_us:主要是用来设置cgroup获得CPU资源的周期,单位为微秒。 cpu.rt_runtime_us:主要是用来设置cgroup中的任务可以最长获得CPU资源的时间,单位为微秒。设定这个值可以访问某个cgroup独占CPU资源。最长的获取CPU资源时间取决于逻辑CPU的数量。比如cpu.rt_runtime_us设置为2000000.2秒),cpu.rt_period_us设置为10000001秒)。在单个逻辑CPU上的获得时间为每秒为0.2秒。 2个逻辑CPU,获得的时间则是0.4秒。

 

默认分组下的两个配置的值

hikey:/dev/cpuctl # cat cpu.rt_period_us                                       
1000000
hikey:/dev/cpuctl # cat cpu.rt_runtime_us                                      
800000

即单个逻辑CPU下每一秒内可以获得0.8秒的执行时间。

 

bg_non_interactive分组下的两个配置的值

hikey:/dev/cpuctl/bg_non_interactive # cat cpu.rt_period_us                    
1000000
hikey:/dev/cpuctl/bg_non_interactive # cat cpu.rt_runtime_us                   
700000

即单个逻辑CPU下每一秒可以获得0.7秒的执行时间。

 

Activity & Service

 

Android中,一个应用(进程)既可以由apps切换到bg_non_interactive,也可以切换回来。

 

Activity

当一个Activity处于可见的状态下,那么这个应用进程就属于apps分组。

 

Service

当Service调用startForeground方法后,那么这个应用进程则是归类于apps分组。

Notification.Builder  builder = newNotification.Builder(this);

builder.setContentTitle("Title");

Notification notification =builder.build();

startForeground(notification.hashCode(),notification);

 

3、如何确定进程的cgroups

       其实在Android中要确定进程的cgroups很简单,主要有以下三个步骤:

第一步,进入已经rootAndroid设备终端;

 

11:10 $ adb shell

root@htc_m8tl:/ # su

root@htc_m8tl:/ #

 

第二步,目标应用的进程id,这里以我们的demo程序(包名为com.droidyue.androidthreadschedule)为例。得到的进程id22871

 

root@htc_m8tl:/ # ps | grep com.droidyue

u0_a1434  22871 23723 970040 54304ffffffff 400a045c S com.droidyue.androidthreadschedule

 

第三步,利用进程id查看其所在的cgroups

 

2|root@htc_m8tl:/ # cat  /proc/22871/cgroup

3:cpu:/apps

2:memory:/

1:cpuacct:/uid/11434


 通过cat /proc/xxx/bg_non_interactive可以看到该进程的cgroup信息:

hikey:/proc/1735 # cat cgroup                                                  
4:cpuset:/system-background
3:cpu:/bg_non_interactive
2:memory:/
1:cpuacct:/

通过上面这三个步骤的操作,就可以得到进程所在的cgroups分组。

 

    以上就是Android进程线程cgroups的使用相关介绍,大家自行动手设置一下,加深印象,如果设置过程中还有什么疑问,可以去麦子圈问答版块提问,会有相关Android大牛为你及时解答。

 


Linux的Cgroup

原文地址:http://www.cnblogs.com/yjf512/p/3298582.html

为什么要有cgroup

Linux系统中经常有个需求就是希望能限制某个或者某些进程的分配资源。也就是能完成一组容器的概念,在这个容器中,有分配好的特定比例的cpu时间,IO时间,可用内存大小等。于是就出现了cgroup的概念,cgroup就是controller group,最初由google的工程师提出,后来被整合进Linux内核中。

Cgroup是将任意进程进行分组化管理的Linux内核功能。cgroup本身提供将进程进行分组化管理的功能和接口的基础结构。

而后的Android操作系统也就凭借着这个技术,为每个应用程序分配不同的cgroup,将每个程序进行隔离,达到了一个应用程序不会影响其他应用程序环境的目的。

概念

task:

一个进程

control group:

控制族群,按照某种标准划分的进程组

hierarchy:

层级,control group可以形成树形的结构,有父节点,子节点,每个节点都是一个control group,子节点继承父节点的特定属性。

subsystem:

子系统。

子系统就是资源控制器,每种子系统就是一个资源的分配器,比如cpu子系统是控制cpu时间分配的。

可以使用lssubsys -al来列出系统支持多少种子系统,和使用ls /sys/fs/cgroup/ (ubuntu)来显示已经挂载的子系统:

Image(6)

可以看到这里的几个子系统,比如cpu是控制cpu时间片的,memory是控制内存使用的。

如何安装cgroup

安装cgroup:

apt-get install cgroup-bin

如何为cgroup分配限制的资源

首先明白下,是先挂载子系统,然后才有control group的。意思就是比如想限制某些进程的资源,那么,我会先挂载memory子系统,然后在memory子系统中创建一个cgroup节点,在这个节点中,将需要控制的进程id写入,并且将控制的属性写入。

拿memory子系统为例:

通过查看cgroup的配置文件:

cat /etc/cgconfig.conf

Image(7)

看到memory子系统是挂载在目录/sys/fs/cgroup/memory下

进入这个目录

创建一个文件夹,就创建了一个control group了

mkdir test

发现test目录下自动创建了许多文件:

Image(8)

这些文件的含义如下:

Image(9)

于是,限制内存使用我们就可以设置memory.limit_in_bytes

Image(10)

将一个进程加入到这个test中

echo $$ > tasks

这样就将当前这个终端进程加入到了内存限制的cgroup中了。

将这个cgroup删除只要删除目录就行了

rmdir test



GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐