我可以在Python中创建一个子进程并暂停它:
proc = subprocess.pOpen(['binary', 'arg1', 'arg2'])
# Subprocess was created in a running state
proc_handle = psutil.Process(pid=proc.pid)
proc_handle.suspend()
# Subprocess is now suspended
proc_handle.resume()
# Subprocess is now running
问题:如何在暂停状态下启动子进程?我知道创建子进程和挂起它之间的时间很短,但我对无缝解决方案很感兴趣。此外,我知道我可以轻松地将子进程包装在父进程中,该进程将在继续之前等待恢复信号,但是如果存在的话,我想要一个不那么hacky,更优雅的解决方案。此外,我知道我可以创建一个围绕子进程的类包装器,它不会创建它直到我真的想要运行它,但后来我还没有为它分配一个PID而我赢了#39 ; t能够检查统计数据,例如未启动进程的内存占用情况。
如果我能做到这一点,我会很高兴:
cmd = ['binary', 'arg1', 'arg2']
proc = subprocess.pOpen(cmd, autostart=False) # autostart argument does not exist
# Subprocess was created, so it had a PID and has a memory footprint,
# but is suspended and no code had been run
我在使用autostart = False编写上述pOpen示例时认识到,由于进程的运行方式,这可能无法实现。如果我想在main()函数的开头打破,那么一些代码将作为静态初始化的一部分执行。理想情况下,在创建和初始化进程内存之后,子进程将在该步骤之前暂停。
注意:我特别感兴趣的是在Linux环境中解决这个问题,但如果存在,那么独立于平台的解决方案就会很棒。
答案 0 :(得分:2)
fork()
之后exec()
这个很容易,但不太有用:
import subprocess, os, signal
proc = subprocess.Popen(
['binary', 'arg1', 'arg2'],
preexec_fn=lambda: os.kill(os.getpid(), signal.SIGSTOP),
)
为什么“不那么有用”?因为虽然preexec_fn
在新PID中运行,但您的意图似乎涉及收集内存使用情况的统计信息(在程序执行malloc()
调用之前可以完成的程度),直到exec
发生,你将测量其内存的程序是Python解释器。
exec()
main()
之后停止
首先,为Linux加载程序(ld.so
)编译审计模块,类似于以下内容:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
unsigned int la_version(unsigned int version) {
return version;
}
/* To have stronger guarantees of immediacy, I might replace this with flock()ing a
* lockfile, and releasing that lock from the parent when ready to continue. YMMV,
* consider this a stub intended to be replaced.
*/
void la_preinit(uintptr_t *cookie) {
kill(getpid(), SIGSTOP);
unsetenv("LD_AUDIT"); /* avoid our children getting stopped the same way */
}
然后,在运行子进程时指定它:
newEnv = dict(os.environ)
newEnv['LD_AUDIT'] = '/path/to/above/library.so'
proc = subprocess.Popen(['binary', 'arg1', 'arg2'], env=newEnv)
在 la_preinit
启动之前, main()
由加载程序调用。