如何在 C 中的进程完成后跟踪子进程使用的内存
how to trace memory used by a child process after the process finished in C
我有一个进程使用 execve(2) 系统调用派生一个子进程来执行可执行程序
父进程等待子进程完成使用 wait4(2) 系统调用
我需要知道子进程 运行 的应用程序 运行 使用的时间和内存
我使用 wait4(2) 系统调用返回的 (rusage) 对象来获取我想要的时间值,但经过一些研究后,我发现应用程序使用的内存无法通过同一个 (usage) 对象实现,因为它已经不现在以这种方式支持
一种方法是使用 /proc 伪文件系统并解析 /proc/[pid]
目录中的状态或 statm 文件
假设我想解析 /proc/[pid]/status
我在这个文件中需要的是指定 KB
中数据使用的内存的字段 vmdata
当我在子进程完成之前读取文件时,未显示字段 vmdata "it's missing from the file!!" 显然进程未完成!所以我无法准确确定用于孔工作的内存
当我在子进程完成后读取文件时,目录 /proc/[pid] 将被删除!我建议当进程结束时,进程数据会被释放
请 !!解决这个问题的任何想法或其他方式的任何想法?
谢谢...
VmData 字段似乎只存在于 运行ning 进程中。我不知道你为什么决定不这样做。只需 运行 grep VmData /proc/$$/status
,您就会在当前的 shell 流程中看到它。
你的问题中有三个有趣的时间点。第一个是当您的 child 进程处于 运行ning 时。第二个是当它不再是运行ning,而是以丧尸的形式存在,第三个是你收割它之后,它不存在了。您似乎错过了第 2 点。
如果你想在进程处于僵尸状态时捕获它(即 - 它已经退出,但尚未收割)你将需要找到一种方法来通知它已完成而不调用 wait
, 这将使它消失。我推荐的方法是注册一个 SIGCHLD
处理程序。它会在您的进程存在时被调用,但不会将其从系统中删除。到那个时候,/proc/pid/status
仍然存在。
不幸的是,VmData
不存在僵尸进程。您的选择是定期采样 VmData
,或者在进程即将终止时停止进程,但实际上尚未这样做。
有一种无竞争的方法可以做到这一点,但不幸的是,它需要使用有点黑魔法的 ptrace
系统调用。如何使用 ptrace
的完整解释超出了本答案的范围。然而,简而言之,您的 child 进程在调用 execve
之前,使用 PTRACE_TRACEME
参数调用 ptrace
。然后,您的 parent 进程将成为您的 child 进程的调试器。每当您的 child 进程即将执行某些特殊操作时,它都会收到 wait
通知。
这需要花一些时间来尝试调用,但这会让您知道您的 child 何时即将退出,但实际上尚未退出。
我有一个进程使用 execve(2) 系统调用派生一个子进程来执行可执行程序
父进程等待子进程完成使用 wait4(2) 系统调用
我需要知道子进程 运行 的应用程序 运行 使用的时间和内存
我使用 wait4(2) 系统调用返回的 (rusage) 对象来获取我想要的时间值,但经过一些研究后,我发现应用程序使用的内存无法通过同一个 (usage) 对象实现,因为它已经不现在以这种方式支持
一种方法是使用 /proc 伪文件系统并解析 /proc/[pid]
目录中的状态或 statm 文件
假设我想解析 /proc/[pid]/status
我在这个文件中需要的是指定 KB
中数据使用的内存的字段 vmdata
当我在子进程完成之前读取文件时,未显示字段 vmdata "it's missing from the file!!" 显然进程未完成!所以我无法准确确定用于孔工作的内存
当我在子进程完成后读取文件时,目录 /proc/[pid] 将被删除!我建议当进程结束时,进程数据会被释放
请 !!解决这个问题的任何想法或其他方式的任何想法?
谢谢...
VmData 字段似乎只存在于 运行ning 进程中。我不知道你为什么决定不这样做。只需 运行 grep VmData /proc/$$/status
,您就会在当前的 shell 流程中看到它。
你的问题中有三个有趣的时间点。第一个是当您的 child 进程处于 运行ning 时。第二个是当它不再是运行ning,而是以丧尸的形式存在,第三个是你收割它之后,它不存在了。您似乎错过了第 2 点。
如果你想在进程处于僵尸状态时捕获它(即 - 它已经退出,但尚未收割)你将需要找到一种方法来通知它已完成而不调用 wait
, 这将使它消失。我推荐的方法是注册一个 SIGCHLD
处理程序。它会在您的进程存在时被调用,但不会将其从系统中删除。到那个时候,/proc/pid/status
仍然存在。
不幸的是,VmData
不存在僵尸进程。您的选择是定期采样 VmData
,或者在进程即将终止时停止进程,但实际上尚未这样做。
有一种无竞争的方法可以做到这一点,但不幸的是,它需要使用有点黑魔法的 ptrace
系统调用。如何使用 ptrace
的完整解释超出了本答案的范围。然而,简而言之,您的 child 进程在调用 execve
之前,使用 PTRACE_TRACEME
参数调用 ptrace
。然后,您的 parent 进程将成为您的 child 进程的调试器。每当您的 child 进程即将执行某些特殊操作时,它都会收到 wait
通知。
这需要花一些时间来尝试调用,但这会让您知道您的 child 何时即将退出,但实际上尚未退出。