关闭管道python子进程的stdout

13 python shell subprocess pipeline

以下是我在python子进程模块文档中可以阅读的内容:

Replacing shell pipeline

    output=`dmesg | grep hda`
    ==>
    p1 = Popen(["dmesg"], stdout=PIPE)
    p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
    p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
    output = p2.communicate()[0]

The p1.stdout.close() call after starting the p2 is important in order for p1
to receive a SIGPIPE if p2 exits before p1.
Run Code Online (Sandbox Code Playgroud)

我真的不明白为什么在创建p2之后我们必须关闭p1.stdout.什么时候完全执行p1.stdout.close()?当p2永远不会结束时会发生什么?当p1或p2结束时会发生什么?

And*_*ark 15

Wikipedia中,SIGPIPE是在尝试写入管道而没有连接到另一端的进程时发送给进程的信号.

当您第一次创建p1使用时stdout=PIPE,有一个进程连接到管道,这是您的Python进程,您可以使用读取输出p1.stdout.

当您创建p2使用stdin=p1.stdout现在有连接于管两个过程p1.stdout.

通常,当您在管道中运行进程时,您希望所有进程在任何进程结束时结束.为了自动执行此操作,您需要关闭,p1.stdout因此p2.stdin是唯一连接到该管道的进程,这样如果p2结束并将p1其他数据写入stdout,它将收到一个SIGPIPE,因为不再有任何进程连接到该管道.