我正在创建一个需要产生多个进程的库。
我想知道测试期间产生的所有后代进程的集合。这对于在通过的测试结束时终止行为良好的守护程序或通过获取测试失败后存在的任何进程的堆栈跟踪信息来调试死锁/挂起进程很有用。
由于其中某些操作需要生成守护程序(叉,叉,然后让父进程死掉),因此我们无法通过遍历进程树来找到所有进程。
目前我的方法是:
os.register_at_fork
(pid, process start time)
附加到另一个文件中这种方法的缺点是:
multiprocessing
或os.fork
-使用subprocess
或非Python进程生成新的Python进程时不起作用。我正在寻找一种可以避免这两个弊端的跟踪子进程的方法。
我考虑过的替代品:
有人可以提出解决该问题的方法,以避免上述方法的弊端和弊端吗?我现在仅对Linux感兴趣,理想情况下,它不应该要求4.15之后的内核。
答案 0 :(得分:0)
对于subprocess.Popen
,有一个preexec_fn
参数可调用-您可以通过它来破解自己的方式。
或者,看看cgroups(控制组)-我相信它们可以处理棘手的情况,例如创建守护程序等等。
答案 1 :(得分:0)
鉴于原始帖子的限制,我使用了以下方法:
putenv("PID_DIR", <some tempdir>)
fork
和clone
覆盖,这些版本将把流程开始时间追溯到$PID_DIR/<pid>
。覆盖是使用plthook完成的,并且适用于所有已加载的共享对象。 dlopen
也应该被覆盖,以覆盖任何其他动态加载的库中的功能。__libc_start_main
,fork
和clone
的库设置为LD_PRELOAD
。here的初始实现可用,其用法如下:
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())