Linux中使用cgroup freezer可精细冻结进程,需先挂载freezer子系统,创建cgroup目录,将进程PID写入tasks文件,再通过写FROZEN到freezer.state实现冻结,THAWED恢复,操作需root权限,注意v1与v2版本路径及控制方式差异。

Linux中要冻结进程,我们通常会利用cgroup的freezer子系统。这个机制允许你将一个或一组进程暂停(freeze)或恢复(unfreeze),就像给它们打了个“暂停键”。这在需要对某个服务进行维护、调试,或者在某些特殊场景下需要暂时隔离资源时,简直是神器。它不像
kill -STOP
要使用cgroup freezer,基本流程是这样的:
挂载cgroup文件系统:如果你的系统还没有挂载cgroup文件系统,或者freezer子系统没有挂载,你需要先做这一步。通常,现代Linux发行版已经默认挂载了。
# 检查freezer是否已挂载 mount -t cgroup | grep freezer # 如果没有,手动挂载(通常不需要,系统会自动处理) # sudo mkdir /sys/fs/cgroup/freezer # sudo mount -t cgroup -o freezer freezer /sys/fs/cgroup/freezer
我一般会直接去
/sys/fs/cgroup/freezer
创建新的cgroup目录:在freezer子系统下创建一个新的目录,这代表一个独立的cgroup。
sudo mkdir /sys/fs/cgroup/freezer/my_frozen_group
给它起个有意义的名字,这样以后管理起来方便。
将进程添加到cgroup:把你想冻结的进程的PID写入到这个cgroup的
tasks
# 在一个终端运行 while true; do echo "Running..."; sleep 1; done & # 获取其PID PID=$! echo "Test process PID: $PID"
然后将它加入cgroup:
sudo sh -c "echo $PID > /sys/fs/cgroup/freezer/my_frozen_group/tasks"
这里要注意权限问题,直接
echo $PID > file
sudo sh -c "..."
冻结进程:通过修改
freezer.state
sudo sh -c "echo FROZEN > /sys/fs/cgroup/freezer/my_frozen_group/freezer.state"
执行完这步,你会发现上面那个
while true
恢复进程:当需要恢复时,将状态改回
THAWED
sudo sh -c "echo THAWED > /sys/fs/cgroup/freezer/my_frozen_group/freezer.state"
进程会立即恢复执行。
清理cgroup:当你不再需要这个cgroup时,需要先确保里面没有进程,然后才能删除它。
# 将进程从cgroup中移除(通常在进程结束后或移到根cgroup) # 如果进程还在运行,可以把它移回根cgroup: # sudo sh -c "echo $PID > /sys/fs/cgroup/freezer/tasks" # 或者直接kill掉进程 # kill $PID # 确认tasks文件为空 cat /sys/fs/cgroup/freezer/my_frozen_group/tasks # 删除cgroup目录 sudo rmdir /sys/fs/cgroup/freezer/my_frozen_group
清理工作很重要,不然会留下一些无用的目录。
cgroup freezer的核心机制在于它利用了Linux内核的进程调度器和信号处理机制。当一个进程被标记为
FROZEN
SIGSTOP
SIGSTOP
TASK_STOPPED
TASK_STOPPED
kill -STOP
T
具体来说,当freezer子系统收到
FROZEN
SIGKILL
SIGCONT
这种内核层面的控制,使得freezer比传统的
SIGSTOP
SIGCONT
使用cgroup freezer虽然强大,但也并非没有坑。我个人就遇到过一些情况,分享一下:
权限问题:这是最常见的。操作
/sys/fs/cgroup
sudo
Permission denied
echo "..." > file
sudo sh -c "..."
sudo echo "..." > file
进程无法冻结:有些非常底层的内核线程(kernel threads)可能无法被完全冻结,或者行为不符合预期。不过,对于我们日常的用户空间应用,这通常不是问题。如果遇到某个进程怎么也冻结不了,首先检查它是否是内核线程,其次确认它是否真的在你的cgroup里。
误操作导致系统不稳定:如果你不小心把关键系统进程(比如
systemd
cgroup v1与v2的差异:如果你在不同的Linux发行版或内核版本之间切换,可能会遇到cgroup v1和v2的差异。v2的设计更加统一和简洁,但命令和文件路径可能有所不同。这就像你习惯了旧版软件的界面,突然换了新版,需要重新适应。
清理不彻底:前面提到过,如果cgroup目录里还有进程,你无法直接删除它。有时进程可能因为某种原因僵死,或者你忘记将它们移出,导致cgroup目录无法删除,需要手动清理或重启。
死锁或资源占用:虽然进程被冻结了,但它占用的内存、打开的文件句柄、网络连接等资源仍然存在。如果冻结了大量进程,或者冻结了一个持有重要锁的进程,可能会导致其他进程因为等待这些资源而阻塞,甚至引发死锁。这一点在进行系统维护时尤其需要注意。
cgroup v1和v2是Linux控制组的两个主要版本,它们在架构和使用方式上存在显著差异,freezer子系统也不例外。理解这些差异对于在不同系统上正确使用cgroup至关重要。
cgroup v1 (Legacy): 在cgroup v1中,每个子系统(如
cpu
memory
freezer
freezer
cpu
/sys/fs/cgroup/freezer
freezer
tasks
cgroup.procs
freezer.state
freezer.state
FROZEN
THAWED
cgroup v2 (Unified Hierarchy): cgroup v2引入了统一的层级结构,所有的子系统都挂载在同一个根目录下(通常是
/sys/fs/cgroup
/sys/fs/cgroup
freezer
cgroup.freeze
1
cgroup.freeze
0
# 假设你的cgroup v2根目录是 /sys/fs/cgroup # 创建cgroup sudo mkdir /sys/fs/cgroup/my_frozen_group_v2 # 启用freezer控制器 sudo sh -c "echo '+freezer' > /sys/fs/cgroup/my_frozen_group_v2/cgroup.subtree_control" # 添加进程 sudo sh -c "echo $PID > /sys/fs/cgroup/my_frozen_group_v2/cgroup.procs" # 冻结 sudo sh -c "echo 1 > /sys/fs/cgroup/my_frozen_group_v2/cgroup.freeze" # 解冻 sudo sh -c "echo 0 > /sys/fs/cgroup/my_frozen_group_v2/cgroup.freeze"
在我看来,cgroup v2的设计更加优雅和一致,它解决了v1中一些固有的复杂性。但由于历史原因,很多系统仍然在使用v1,或者同时支持v1和v2(混合模式)。因此,在实际操作时,你需要先确定你的系统是哪种模式,或者默认使用哪种版本,才能选择正确的命令和路径。可以通过
mount -t cgroup2
以上就是如何在Linux中进程冻结 Linux cgroup freezer使用的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号