cgroup在Linux/Android几篇文章(主要关注cgroup在Android、Linux上的应用)
Android进程线程之cgroups的使用详解
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_releasecgroup.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. 再次查看进程id为11950的CPU使用率,已成功降低到10%左右。
cgroups在Android中的应用
在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
1、cpu.share
cpu.share文件中保存了整数值,用来设置cgroup分组任务获得CPU时间的相对值。举例来说,cgroup A和cgroup B的cpu.share值都是1024,那么cgroup A 与cgroup B中的任务分配到的CPU时间相同,如果cgroup C的cpu.share为512,那么cgroup C中的任务获得的CPU时间是A或B的一半。
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%
2、cpu.rt_period_us与cpu.rt_runtime_us
cpu.rt_period_us:主要是用来设置cgroup获得CPU资源的周期,单位为微秒。 cpu.rt_runtime_us:主要是用来设置cgroup中的任务可以最长获得CPU资源的时间,单位为微秒。设定这个值可以访问某个cgroup独占CPU资源。最长的获取CPU资源时间取决于逻辑CPU的数量。比如cpu.rt_runtime_us设置为200000(0.2秒),cpu.rt_period_us设置为1000000(1秒)。在单个逻辑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很简单,主要有以下三个步骤:
第一步,进入已经root的Android设备终端;
11:10 $ adb shell
root@htc_m8tl:/ # su
root@htc_m8tl:/ #
第二步,目标应用的进程id,这里以我们的demo程序(包名为com.droidyue.androidthreadschedule)为例。得到的进程id为22871
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)来显示已经挂载的子系统:
可以看到这里的几个子系统,比如cpu是控制cpu时间片的,memory是控制内存使用的。
如何安装cgroup
安装cgroup:
apt-get install cgroup-bin
如何为cgroup分配限制的资源
首先明白下,是先挂载子系统,然后才有control group的。意思就是比如想限制某些进程的资源,那么,我会先挂载memory子系统,然后在memory子系统中创建一个cgroup节点,在这个节点中,将需要控制的进程id写入,并且将控制的属性写入。
拿memory子系统为例:
通过查看cgroup的配置文件:
cat /etc/cgconfig.conf
看到memory子系统是挂载在目录/sys/fs/cgroup/memory下
进入这个目录
创建一个文件夹,就创建了一个control group了
mkdir test
发现test目录下自动创建了许多文件:
这些文件的含义如下:
于是,限制内存使用我们就可以设置memory.limit_in_bytes
将一个进程加入到这个test中
echo $$ > tasks
这样就将当前这个终端进程加入到了内存限制的cgroup中了。
将这个cgroup删除只要删除目录就行了
rmdir test
更多推荐
所有评论(0)