python - 将 fork 的 python 进程的输出重定向到管道

标签 python python-2.7 pipe stdout

我想将一些已记录的进程从 fork 的 Python 进程写入父进程,因此我使用管道对:

rpipe, wpipe = os.pipe()

pid = os.fork()
if pid == -1:
    raise TestError("Failed to fork() in prepare_test_dir")

if pid == 0:
    # Child -- do the copy, print log to pipe and exit
    try:
        os.close(rpipe)
        os.dup2(wpipe, sys.stdout.fileno())
        os.dup2(wpipe, sys.stderr.fileno())
        os.close(wpipe)

        self._prepare_test_dir(test)

        sys.stdout.write(self.copy_log)
    finally:
        os._exit(1)

os.close(wpipe)

_, status = os.waitpid(pid, 0)

# XXX: if copy_log is larger than PIPE_BUF (4-8k), everything
# then is going badly
outf = os.fdopen(rpipe)
self.copy_log = outf.read()

return os.WEXITSTATUS(status)

它不起作用,self.copy_log 中什么也没有出现。我还尝试使用 fdopen 显式构造 stdout 对象:

sys.stdout = os.fdopen(wpipe, 'w')

也不工作。但是,如果我将 print 放在 dup2 之前:

if pid == 0:
    try:
        print 'HELLO'
        os.close(rpipe)
        os.dup2(wpipe, sys.stdout.fileno())
        os.dup2(wpipe, sys.stderr.fileno())
        ...

复制日志已成功传递给父级,并且“HELLO”已打印到控制终端。我认为 print 会以某种方式影响 sys.stdout (通过延迟初始化或其他方式)。有什么想法吗?

我在各种 Linux 平台上使用 Python 2.6 和 2.7。

最佳答案

问题似乎不在与 pipeline/dup2 相关的代码中,而是在 os._exit 中。这是杀死 python 解释器的残酷方法(但对于 fork 进程来说是可以的,因此它不会触及“共享”对象),但它会导致 stdoutstderr 不被刷新,并且数据丢失。

我在 child 中看到以下代码:

try:
    os.close(rpipe)
    os.dup2(wpipe, sys.stdout.fileno())
    os.dup2(wpipe, sys.stderr.fileno())
    os.close(wpipe)

    print 'aaaaaaaaa'
except:
    traceback.print_exc(20, sys.stderr)
finally:
    sys.stdout.flush()
    sys.stderr.flush()
    os._exit(1)

关于python - 将 fork 的 python 进程的输出重定向到管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31503230/

相关文章:

c++ - 如何检查我的程序是否有数据通过管道传输到其中

c - 只有一条消息通过管道

Python 将字典列表转换为另一个字典列表

python - 如何使这个 for 循环在 Python 中工作?

python - 带有位置参数的函数的装饰器,带有通常命名的参数

xcode - 可执行管道输入?

Python:产生另一个程序

python - Pygame-太空侵略者子弹

python - pyPdf:非法 UTF-16 代理

python - 遍历大量文件并保存数据图的最快/最有效的方法是什么?