如何捕获从Python的mulitprocessing.Process
库启动的进程的特定目标的stdout / stderr,理想情况下不需要对目标函数进行特殊修改?
e.g。
p = Process(target=myfunc)
p.daemon=True
p.start()
p.join()
print p.exitcode, p.stderr.getvalue()
我知道如何使用自定义文件对象覆盖sys.stdout / sys.stderr并使用multiprocessing.Queue在进程之间重定向IO,但这需要修改目标函数以将其输出写入队列。
Process
可以使用这样的内容吗?我假设它在某种程度上,因为我能够在运行时在终端中看到进程的输出,即使我无法从父进程记录它。
答案 0 :(得分:1)
这不是答案,而是长篇评论。
我会创建一个包装器函数来替换sys.stderr并将其写入文件/管道,然后在进程运行之后/ stderr被读入父级。原因是:
如果不改变功能
,这种接缝会很困难多处理不使用子进程。
您将Process子类化并设置Process.Popen
以替换multiprocessing.forking.Popen
。
替换multiprocessing.forking.Popen
必须为平台'win32'和'not win32'实现不同的代码,导致两个不同的子类或使用子进程。
从我的角度来看,修改multiprocessing.forking.Popen
以使用subprocess
应该是您最好的尝试。
在Process.start()
from .forking import Popen
self._popen = Popen(self) # also self.Popen
在multiprocessing.forking
class Popen(object):
def __init__(self, ...):
# ...
# for windows
hp, ht, pid, tid = _subprocess.CreateProcess(
_python_exe, cmd, None, None, 1, 0, None, None, None
)
现在看看子流程:
(p2cread, p2cwrite,
c2pread, c2pwrite,
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
self._execute_child(args, executable, preexec_fn, close_fds,
cwd, env, universal_newlines,
startupinfo, creationflags, shell,
p2cread, p2cwrite,
c2pread, c2pwrite,
errread, errwrite)
self.stdout = os.fdopen(c2pread, 'rU', bufsize)