[英]How to track all descendant processes in Linux
I am making a library that needs to spawn multiple processes. 我正在创建一个需要生成多个进程的库。
I want to be able to know the set of all descendant processes that were spawned during a test. 我希望能够知道在测试期间生成的所有后代进程的集合。 This is useful for terminating well-behaved daemons at the end of a passed test or for debugging deadlocks/hanging processes by getting the stack trace of any processes present after a failing test.
这对于在通过测试结束时终止行为良好的守护进程或通过获取失败测试后出现的任何进程的堆栈跟踪来调试死锁/挂起进程非常有用。
Since some of this requires spawning daemons (fork, fork, then let parent die), we cannot find all processes by iterating over the process tree. 由于其中一些需要产生守护进程(fork,fork,然后让父模具),我们无法通过遍历进程树来找到所有进程。
Currently my approach is: 目前我的方法是:
os.register_at_fork
os.register_at_fork
注册处理程序 (pid, process start time)
into another file (pid, process start time)
追加到另一个文件中 The downsides of this approach are: 这种方法的缺点是:
multiprocessing
or os.fork
- does not work when spawning a new Python process using subprocess
or a non-Python process. multiprocessing
或os.fork
- 在使用subprocess
进程或非Python进程生成新的Python进程时不起作用。 I am looking for a different way to track child processes that avoids these 2 downsides. 我正在寻找一种不同的方法来跟踪避免这两个缺点的子进程。
Alternatives I have considered: 我考虑的替代方案:
Can someone suggest an approach to this problem that avoids the pitfalls and downsides of the ones above? 有人可以提出一个方法来解决这个问题,避免上述问题的陷阱和缺点吗? I am only interested in Linux right now, and ideally it shouldn't require a kernel later than 4.15.
我现在只对Linux感兴趣,理想情况下它不应该要求4.15之后的内核。
For subprocess.Popen
, there's preexec_fn
argument for a callable -- you can hack your way through it. 对于
subprocess.Popen
,有preexec_fn
一个可调用的参数-你可以通过它破解你的方式。
Alternatively, take a look at cgroups (control groups) -- I believe they can handle tricky situations such as daemon creation and so forth. 或者,看看cgroups (控制组) - 我相信他们可以处理棘手的情况,例如守护进程创建等等。
Given the constraints from my original post, I used the following approach: 考虑到我原帖的限制,我使用了以下方法:
putenv("PID_DIR", <some tempdir>)
fork
and clone
with versions which will trace the process start time to $PID_DIR/<pid>
. $PID_DIR/<pid>
版本覆盖fork
和clone
。 The override is done using plthook and applies to all loaded shared objects. dlopen
should also be overridden to override the functions on any other dynamically loaded libraries. dlopen
以覆盖任何其他动态加载的库上的函数。 __libc_start_main
, fork
, and clone
as LD_PRELOAD
. __libc_start_main
, fork
和clone
实现的库设置为LD_PRELOAD
。 An initial implementation is available here used like: 这里有一个初始实现,如:
import process_tracker; process_tracker.install()
import os
pid1 = os.fork()
pid2 = os.fork()
pid3 = os.fork()
if pid1 and pid2 and pid3:
print(process_tracker.children())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.