【问题标题】:Running piped subprocesses gives different result when the launch order changes?当启动顺序更改时,运行管道子流程会产生不同的结果?
【发布时间】:2011-04-04 20:10:31
【问题描述】:

我正在使用subprocess.* 运行来自python3 程序的命令管道;我不想 通过 shell,因为我将参数传递给我的子命令,并确保这些不会被 shell 误解,这将是一场噩梦。

subprocess 文档给出了如何做到这一点的示例:

p1 = Popen(command1, stdout=PIPE)
p2 = Popen(command2, stdin=p1.stdout)
p2.wait()
p1.wait()

这很好用。但是,我想知道在生产者之前启动消费者是否更安全,所以

p2 = Popen(command2, stdin=PIPE)
p1 = Popen(command1, stdout=p2.stdin)
p2.wait()
p1.wait()

我希望这会以完全相同的方式表现,但显然他们没有。第一个代码完美无缺;第二,我的程序挂起;如果我查看系统,我可以看到 p1 已死,等待收获,而 p2 永远挂起。有没有合理的解释?

【问题讨论】:

    标签: python-3.x subprocess pipe


    【解决方案1】:

    看起来 p2(消费者)正在挂起,因为它的 stdin 保持打开状态。如果代码这样修改,两个进程都成功完成:

    p2 = Popen(command2, stdin=PIPE)
    p1 = Popen(command1, stdout=p2.stdin)
    p1.wait()
    p2.stdin.close()
    p2.wait()
    

    我敢打赌,这就是泄漏抽象定律的实际应用。

    【讨论】:

    • 哇,看来你是对的。但我仍然不明白为什么需要这样做。行为差异从何而来?在子进程调用 exec() 之后,它们所做的事情不在父进程的控制范围内,对吧?是否可能涉及父级的GC?
    猜你喜欢
    • 2017-08-16
    • 1970-01-01
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 1970-01-01
    • 2012-05-02
    相关资源
    最近更新 更多