关闭管道Python子进程的标准输出

发布于 2024-12-04 02:50:55 字数 569 浏览 0 评论 0原文

这是我在 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.

我真的不明白为什么我们必须在创建 p2 后关闭 p1.stdout 。 p1.stdout.close() 到底是什么时候执行的? 当 p2 永远不会结束时会发生什么? 当 p1 或 p2 都没有结束时会发生什么?

Here is what I can read in the python subprocess module documentation:

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.

I don't really understand why we have to close p1.stdout after have created p2.
When is exactly executed the p1.stdout.close()?
What happens when p2 never ends?
What happens when nor p1 or p2 end?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我也只是我 2024-12-11 02:50:55

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

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

当您使用 stdin=p1.stdout 创建 p2 时,现在有两个进程连接到管道 p1.stdout

通常,当您在管道中运行进程时,您希望在任何进程结束时所有进程也结束。为了自动发生这种情况,您需要关闭p1.stdout,以便p2.stdin是附加到该管道的唯一进程,这样如果p2结束并且 p1 将附加数据写入 stdout,它将收到 SIGPIPE,因为不再有任何进程附加到该管道。

From Wikipedia, SIGPIPE is the signal sent to a process when it attempts to write to a pipe without a process connected to the other end.

When you first create p1 using stdout=PIPE, there is one process connected to the pipe, which is your Python process, and you can read the output using p1.stdout.

When you create p2 using stdin=p1.stdout there are now two processes connected to the pipe p1.stdout.

Generally when you are running processes in a pipeline you want all processes to end when any of the processes end. For this to happen automatically you need to close p1.stdout so p2.stdin is the only process attached to that pipe, this way if p2 ends and p1 writes additional data to stdout, it will receive a SIGPIPE since there are no longer any processes attached to that pipe.

神也荒唐 2024-12-11 02:50:55

好的,我明白了。
p1.stdout 从我的 python 脚本中关闭,但在 p2 中保持打开状态,然后 p1 和 p2 一起通信。
除非 p2 已经关闭,否则 p1 会收到 SIGPIPE。
我说得对吗?

OK I see.
p1.stdout is closed from my python script but remains open in p2, and then p1 and p2 communicate together.
Except if p2 is already closed, then p1 receives a SIGPIPE.
Am I correct?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文