Linux cgroup v2 cgroup.events 怎样监控层级冻结状态
在生产环境里,清理一个服务的 cgroup 或等待冻结完成时,最容易混淆的是“里面没有进程”和“已经冻结”这两个状态。Linux cgroup v2 的 cgroup.events 提供了两个只读字段:populated 表示当前 cgroup 及其子孙层级是否还有活进程,frozen 表示冻结状态是否已经完成。它们可以一起用于清理判断,但不能互相替代。
官方文档:https://docs.kernel.org/admin-guide/cgroup-v2.html
实际监控时先读populated判断层级是否为空,再读frozen判断冻结是否完成;populated=0只能说明没有活进程,不能证明 cgroup 已经冻结。
先分清 cgroup.events 的两个字段
cgroup.events 是非根 cgroup 中的只读平面键值文件。它的值属于当前层级的状态快照,但两个字段的观察范围不同:
populated:当前 cgroup 或它的任意子孙 cgroup 中存在活进程时为1,整个层级没有活进程时为0。frozen:当前 cgroup 处于冻结状态时为1,否则为0。它反映的是冻结状态,而不是进程数量。

这一区分很重要:一个 cgroup 可以没有进程但没有执行过冻结,也可以在冻结期间仍然保留属于它或子孙层级的进程。监控代码应该按字段语义命名,避免把一个布尔值包装成含义更宽的 is_ready。
用只读文件读取层级状态
先把目标限定为非根 cgroup,再读取文件。下面的示例只做状态读取,不写入 cgroup.freeze,适合作为发布后的低风险复查脚本。路径应替换为实际服务对应的 cgroup 目录。
#!/usr/bin/env bash
# 读取目标 cgroup 的只读状态,不改变 cgroup 配置。
set -eu
# 生产环境通过参数传入目录,默认值只作为示例路径。
CGROUP_DIR="${1:-/sys/fs/cgroup/my-service}"
EVENTS_FILE="$CGROUP_DIR/cgroup.events"
# 先确认目标是非根 cgroup 且接口文件可读。
if [ ! -r "$EVENTS_FILE" ]; then
echo "无法读取 $EVENTS_FILE" >&2
exit 1
fi
# 只提取内核定义的两个字段,忽略未来可能新增的键。
populated=""
frozen=""
while IFS=' ' read -r key value _; do
case "$key" in
populated) populated="$value" ;;
frozen) frozen="$value" ;;
esac
done
脚本只依赖键名,不依赖字段顺序。内核文档明确提醒,键值文件应按键查找而不是按固定位置解析;这样即使接口将来增加字段,也不会把新字段误读成旧含义。
把空层级和冻结完成拆成两个判断
如果目标是回收一个已经退出的服务,通常先关心 populated=0:它说明当前 cgroup 及后代没有活进程,可以进入清理候选状态。如果目标是等待冻结动作完成,则应等待 frozen=1。两者同时出现时,说明层级既没有活进程,又处于冻结状态;但这不是所有场景都要求的组合。
| 状态 | 可以得出的结论 | 不能得出的结论 |
|---|---|---|
populated=0 | 当前层级与子孙层级没有活进程 | 不能证明已经冻结 |
frozen=1 | 冻结状态已经完成 | 不能单独证明层级为空 |
populated=1,frozen=1 | 仍有进程,但这些进程处于冻结层级影响范围 | 不能把冻结当成退出或清理完成 |
populated=0,frozen=0 | 层级为空且当前没有冻结状态 | 不能推断此前是否发生过冻结 |
下面是一个不依赖额外监控代理的轮询思路。它适合低频维护窗口;高频场景应把文件变更通知交给已有的事件采集器,并在收到事件后重新读取完整文件。
#!/usr/bin/env bash
# 轮询直到观察到指定状态;每次都重新读取完整键值文件。
set -eu
CGROUP_DIR="${1:-/sys/fs/cgroup/my-service}"
EVENTS_FILE="$CGROUP_DIR/cgroup.events"
INTERVAL_SECONDS="${INTERVAL_SECONDS:-1}"
for _ in 1 2 3 4 5 6 7 8 9 10; do
# 默认按未满足处理,避免缺字段时误报成功。
populated="unknown"
frozen="unknown"
while IFS=' ' read -r key value _; do
case "$key" in
populated) populated="$value" ;;
frozen) frozen="$value" ;;
esac
done &2
exit 2
通知、祖先影响和复查边界
内核文档说明,cgroup.events 的值发生变化时通常会生成文件修改事件;populated 的更新还会沿层级递归影响相关 cgroup。生产实现可以监听文件变化,但通知只说明“状态可能变化”,不应直接把通知名称当成最终状态,正确做法是收到通知后重新读取 cgroup.events。

冻结状态还要考虑祖先 cgroup:如果祖先被冻结,后代也会受到冻结影响。因此复查时至少保留目标路径、读取时间、两个字段值和祖先路径信息。不要只记录一个“冻结成功”的日志字符串,否则出现层级嵌套时很难解释结果来自哪一层。
发布前后的四项检查
- 确认监控对象是非根 cgroup,并且读取权限覆盖
cgroup.events。 - 确认解析逻辑按键名读取,不假设字段顺序,也不把缺失字段当作
0。 - 确认清理条件与冻结条件分开:清理通常看
populated=0,冻结完成看frozen=1。 - 确认收到文件变更通知后会重新读取文件,并为祖先冻结和状态延迟留出复查窗口。
常见问题
populated=0 能说明服务已经安全退出吗?
它只说明该 cgroup 及其子孙层级当前没有活进程。是否可以删除目录、清理外部资源,还要结合服务管理器、挂载点和业务侧退出确认。
为什么 frozen=1 但 populated 仍然是 1?
冻结会停止进程运行,不会把进程从 cgroup 中移除。因此冻结层级仍可能保留进程,两个字段同时为 1 是合理状态。
监听到文件变化后可以直接执行清理吗?
不建议。通知是重新读取的触发信号,不是清理授权。应再次读取 cgroup.events,并结合权限、祖先层级和服务管理器状态做最终判断。
记住一句话:populated 回答“层级里还有没有活进程”,frozen 回答“冻结是否已经完成”。把这两个问题拆开,cgroup v2 的监控日志和清理策略就不容易互相误导。
Linux /proc/PID/statm 怎样区分虚拟内存与常驻内存
- 上一篇
- Linux /proc/PID/statm 怎样区分虚拟内存与常驻内存
- 下一篇
- Linux openat2 resolve flags 怎样限制路径解析范围
-
- 文章 · linux | 10分钟前 | 命令行工具 · linux运维 · 故障排查 · Linux systemd journalctl 日志排查 启动日志 Boot ID systemd-journald
- journalctl -b 怎样筛选本次启动日志
- 311浏览 收藏
-
- 文章 · linux | 12分钟前 | linux运维 · 文件系统 · Linux 文件句柄 name_to_handle_at open_by_handle_at file_handle mount_id
- Linux name_to_handle_at 怎样保存可复用的文件句柄
- 340浏览 收藏
-
- 文章 · linux | 15分钟前 |
- systemd.timer OnBootSec 与 OnUnitActiveSec 的周期触发配置方法
- 351浏览 收藏
-
- 文章 · linux | 15分钟前 |
- systemd socket 单元 Backlog 怎样影响连接排队
- 490浏览 收藏
-
- 文章 · linux | 19分钟前 | linux运维 · 故障排查 · 服务治理 · Linux systemd 故障恢复 服务重启 RestartSec StartLimit Restart RestartSteps
- systemd RestartSec 怎样影响服务重启节奏
- 312浏览 收藏
-
- 文章 · linux | 21分钟前 |
- Linux openat2 resolve flags 怎样限制路径解析范围
- 132浏览 收藏
-
- 文章 · linux | 26分钟前 |
- Linux /proc/PID/statm 怎样区分虚拟内存与常驻内存
- 481浏览 收藏
-
- 文章 · linux | 30分钟前 |
- Linux /proc/PID/fd 怎样判断进程打开的文件
- 313浏览 收藏
-
- 文章 · linux | 32分钟前 | Linux statx STATX_BTIME 文件创建时间
- Linux statx 怎样读取文件创建时间
- 165浏览 收藏
-
- 文章 · linux | 34分钟前 | linux运维 · Linux 线程 i/o 进程 load average total /proc/loadavg running
- Linux /proc/loadavg 的 running 与 total 怎么读
- 329浏览 收藏
-
- 文章 · linux | 18小时前 | linux运维 · Linux 目录清理 tmpfiles.d systemd-tmpfiles 文件系统年龄
- tmpfiles.d d 与 D 类型清理规则有何区别
- 263浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 1029次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 1030次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 1173次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 1134次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 974次使用
-
- Go log/slog 怎样让 Handler 过滤低级别日志
- 2026-10-18 272浏览
-
- 系统证书池在容器里为空应如何处理
- 2026-10-09 233浏览
-
- TLS unknown authority 如何定位根证书来源
- 2026-11-13 282浏览
-
- Prometheus&Grafana性能监控
- 2023-01-26 106浏览
-
- 云计算-带你安装MySQL数据库并去除安全隐患
- 2023-01-14 411浏览

