如何从Python多处理过程中捕获stderr

时间:2014-02-07 21:23:25

标签: python multiprocessing

如何捕获从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可以使用这样的内容吗?我假设它在某种程度上,因为我能够在运行时在终端中看到进程的输出,即使我无法从父进程记录它。

1 个答案:

答案 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)