假设我限制了允许与 cgroup/cpuset 选项一起使用的一组进程的核心。
我需要知道是否有太多线程分配给该 cgroup,以及线程是否正在经历对可用核心的过度竞争。
我怎样才能做到这一点?
如果没有 cgroupups,我只需使用平均负载,根据top
经验,平均负载应小于核心数。有没有类似的东西考虑cgroup/cpuset?
答案1
根据您具体关心的内容,有两种选择:
如果您关心 cgroup 中有多少线程/进程,而不是“平均负载”:
tasks
只需计算cgroup 文件中的行数即可。每当 cgroup 中创建或删除线程或进程时,该文件都会自动更新。
如果您关心实际利用率:
这有点棘手。您可以从上述tasks
文件中获取 cgroup 中的进程/线程列表,然后使用 检查每个 PID 的使用情况/proc
,但这种方法有很多竞争条件,您可以将其作为一项竞技运动来货币化。或者,如果您使用版本 2 cgroup,则可以检查cpu.stat
cgroup 中的文件。该文件将有几行计算 cgroup 消耗的 CPU 时间的微秒数,因此您可以通过每隔一秒检查两次并将差值除以 10000 来获得利用率百分比(对于 100%一个核心的充分利用,两个核心的充分利用为 20%,等等)。可以使用带有 cpuacct 控制器的版本一 cgroup 来完成类似的方法(在该控制器下创建一个 cgroup,镜像您在 cpuset 控制器下创建的 cgroup)。
答案2
我编写了简单的脚本来计算执行该进程的 cgroup 的平均负载。
$ cat loadavg-cgroup.sh
#!/bin/bash
sample_time=${1:-1} # in seconds
sample_count=${2:-10}
sleep_time="$(echo "scale=2 ; ${sample_time}/${sample_count}" | bc)"
cgroup=$(grep '^2:cpu:' /proc/$$/cgroup)
export cgroup
{
for _ in $(seq 1 "${sample_count}" ) ; do
# note, for cgroup v2 use newest pgrep
ps -eLo cgroup,stat | grep "${cgroup}" | grep ' R[l+]*$' --count
sleep "${sleep_time}"
done
} \
| awk '{ sum+=$1 } END { print (sum/NR) - 1 } '
用法:
# To calculate load average for period of 10 seconds
$ ./loadavg-cgroup.sh 10
1.6
评论:
- 采样时间和数量样本的数量被参数化(分别作为第一和第二参数)
- 这是针对 cgroups v1 的,因为我的 WSL2 环境中有这个
- 最新的
pgrep
也可以与搜索 cgroup 一起使用,因此使用它比 ps+grep+grep trio 更好。 - 不包括
ps
在平均负载中 - 这对于进程不在 cgroup 中的情况不起作用,但调整它应该非常简单