我想要运行一个产生子进程的过程,例如,
for i in {1..4}; do
sh -c 'echo $$; for j in {1..3}; do
sh -c "echo ...\$\$; sleep 1"
done'
done
并且我想每 2 秒用 监控一次 CPU 和内存使用情况top
。
- 我可以用 监控它的资源使用情况
top -p <PID>
,但这并没有考虑到孩子的情况。 - 我可以仅用 来监控所有
top
正在运行的进程,但是信息太多了。 - 我可以预先计算 PID 列表,然后将它们全部传递给
top
,但该过程可能会产生新的子进程,这是无法解释的。
我如何才能top
每 2 秒获取一次我正在运行的进程及其产生的任何进程的快照?
有人在这里问过类似的问题,但它是关于在流程结束后将这些信息汇总为一个数字。我的问题是关于在流程仍在进行时持续监控流程。
由于您在评论中提到,在启动母进程之前准备一些事情通常是可行的,并且因为您的示例启动了一个容器,它可能已经这样做了:
只需使用 Linux cgroups 来监控(如果需要,还可以控制和限制)相关进程组所使用的资源。
这很简单:如果您的进程位于 cgroup 中,那么它的子进程也会在同一个 cgroup 中生成。因此,将您的母进程放入它们自己的 cgroup 中(这“基本上是免费的”,默认情况下,新 cgroup 会从父 cgroup 继承所有内容)。然后,定期从 cgroupsv2 控制器轮询该 cgroup 中的进程,并显示它们。整个游戏如下所示:
将其保存到文件中,使该文件可执行(
chmod 755 filename
),并使用父进程的 PID 运行它(/path/to/filename 1234
)。这几乎肯定可以与任何已经是容器的东西一起工作(所以,flatpak、podman 和 docker 容器、apptainer 容器,……)。
在自己的 cgroup 中启动某件事非常简单:
(当然,如果该程序实际上是一种服务,请务必删除
--scope
并作为服务运行;如果它要作为系统运行,而不是作为用户程序运行,请删除--user
。理想情况下,如果它是一项服务,你实际上只需编写 6 行配置即可使其成为具有自己范围的功能齐全的 systemd 服务)有很多种选择。
TTY=pts/*number*
。请注意,您需要打开 TTY 显示。通过按o
或使用O
添加另一个过滤器来启动此过滤。您可以使用多个命令(包括 和screen command
和xterm -e command
)将命令隔离为 tty 上的唯一命令ssh -t localhost command
(这也具有不丢失输出的优点)。V
,然后使用 关闭不需要的父节点v
。这应该允许您将其限制到足以看到您的命令,尽管限制它可能需要一些时间。这可能需要与其他事情相结合,因为通常只有一两棵完整的树。u
。这些技术或其组合可能会给您带来想要的结果。
编辑:为了便于设置,您可能需要
tty;sleep 10
在脚本顶部写一些类似的内容……或者甚至在另一个exec
目标脚本中写一些类似的内容。如果您不介意使用在不同的用户命名空间中运行您的程序,那么您可以根据用户命名空间
unshare
进行过滤。top
您还可以运行
unshare -r <COMMAND>
,然后使用它的 pid 来查找它的用户命名空间。现在,为了查看用户命名空间中的所有进程
top
:按下
f
以选择一个字段使用Down/Up箭头键,导航到
nsUSER
(USER namespace Inode)。按空格键打开它
按“q”返回主
top
视图。按“O”键触发过滤器,并根据用户命名空间过滤进程
完毕。
我自己想到的答案并不像其他人提出的那么好:
然后运行
monitor_with_top <my_PID> 2
每 2 秒打印一次预期的顶部屏幕。(编辑:哦,对了,正如 aviro 指出的那样,
top
只能通过这种方式传递最多 20 个 PID。按照 Marcus Müller 的回答,您可以改用htop
with--tree --readonly
。)由于我也想要类似的功能,所以我编写了一个可以实现该功能的脚本。
该脚本的优点是它
top
连续运行,因此它实际上显示的是最后一个间隔(默认为 3 秒,但可以通过参数更改-d secs
)的 CPU 消耗。之前的答案是
top
每个周期运行一次,在这种情况下top
只显示当时的 CPU 消耗。3 秒平均值更准确。top
它还解决了无法接收超过 20 个 pid 的问题。该脚本需要
top
在“森林视图模式” 1中进行设置:您需要启动top
,按V
切换森林模式,然后按W
将当前设置写入$HOME/.toprc
配置文件2。脚本3连续运行
top
(默认情况下),所有进程都在主机上运行,并进行一些解析sed
以仅显示所需的 pid 及其子进程。这是代码。我没有做过任何认真的测试,也没有考虑过极端情况,我只是让它工作了。也许我将来会改进它。
例子:
请注意,您可以向要传递给 的脚本添加任何标志
top
。例如,如果您想查看完整的命令行,请添加-c
:1我希望
top
有更多的命令行选项,这样就可以从命令行启动森林视图模式,而不必更改默认视图,但这就是它。2在退出 top 之前发出“W”命令,稍后你将能够以完全相同的状态重新启动
3使用 Python 来做这件事可能更加优雅,但是没关系。