cgroups:如何从 cgroup 中分离进程

cgroups:如何从 cgroup 中分离进程

mygroup我在系统中创建了一个 cgroup并在其下运行一个进程

cgexec -g memory,cpu:groupname/mygroup someprocess

现在,过了一段时间,当我觉得不需要担心 cpu 和内存时,如何将进程与我应用的 cgroup 分离

答案1

一旦组组子系统可用(通过安装它),进程始终是子系统的一部分组组在该子系统的层次结构中,最初将是其根组组,除非移至其他组组,它的后代也会出现在那里。 “分离”进程通常意味着将其移(回)到根组组给定子系统的。

假设子系统已经充分安装,则可以通过创建/删除伪目录或向出现在这些目录中的伪文件读取/写入足够的值来使用所有内容,通常如下/sys/fs/cgroup所述man cgroups.7,否则提供的专用命令cgexeccgclassify

这是一个例子(使用cgroupsv1) 从 bash shell 进行说明:

# ls /sys/fs/cgroup/{memory,cpu}/groupname/mygroup
ls: cannot access '/sys/fs/cgroup/memory/groupname/mygroup': No such file or directory
ls: cannot access '/sys/fs/cgroup/cpu/groupname/mygroup': No such file or directory

# cgcreate -g memory,cpu:groupname/mygroup

# ls -d /sys/fs/cgroup/{memory,cpu}/groupname/mygroup
/sys/fs/cgroup/cpu/groupname/mygroup  /sys/fs/cgroup/memory/groupname/mygroup

当然,在创建上述 cgroup 后,可能可以应用一些专用设置。

# cgexec -g memory,cpu:groupname/mygroup sh -c 'echo $$; exec sleep 999'
14682

其他终端:

# grep -w 14682 /sys/fs/cgroup/{memory,cpu}/groupname/mygroup/cgroup.procs 
/sys/fs/cgroup/memory/groupname/mygroup/cgroup.procs:14682
/sys/fs/cgroup/cpu/groupname/mygroup/cgroup.procs:14682
# grep -w 14682 /sys/fs/cgroup/{memory,cpu}/cgroup.procs
#

# cgclassify -g memory,cpu:/ 14682

# grep -w 14682 /sys/fs/cgroup/{memory,cpu}/groupname/mygroup/cgroup.procs
# grep -w 14682 /sys/fs/cgroup/{memory,cpu}/cgroup.procs
/sys/fs/cgroup/memory/cgroup.procs:14682
/sys/fs/cgroup/cpu/cgroup.procs:14682

上面的三个专用命令可以替换为以下简单的 shell 命令:

# mkdir -p /sys/fs/cgroup/{memory,cpu}/groupname/mygroup
# bash -c 'echo $$ | tee /sys/fs/cgroup/{memory,cpu}/groupname/mygroup/cgroup.procs; exec sleep 999'
15533

和(“分离”它):

# echo 15533 | tee /sys/fs/cgroup/{memory,cpu}/cgroup.procs
15533

实际上请注意专用命令cgclassify,至少在cgroupsv1 作用于进程的线程(使用.../tasks)而不是进程本身(使用.../cgroup.procs)。对于简单进程,pid(进程 ID)是唯一的线程,因此任务组 ID(tgid=pid)在两个伪文件中都是相同的,没有区别。对于多线程进程,移动整个进程需要在使用.../tasks或简单使用时识别其所有线程.../cgroup.procs。就在男人身上:

当将 PID 写入 时cgroup.procs,进程中的所有线程都会立即移至新的 cgroup 中。

在cgroups v1中,可以通过将单个线程的线程ID(即clone(2)和gettid(2)返回的内核线程ID)写入taskscgroup目录中的文件来将其移动到另一个cgroup。可以读取该文件来发现属于 cgroup 成员的线程集。

这就是为什么我选择展示和使用.../cgroup.procs之后。当移动像 Firefox、java 应用程序等这样的多线程进程pgrep --lightweight可用于cgclassify为这种情况提供所有任务时,这一点很重要(但要注意竞争)。

相关内容