关闭管道Python子进程的标准输出
这是我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从 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
usingstdout=PIPE
, there is one process connected to the pipe, which is your Python process, and you can read the output usingp1.stdout
.When you create
p2
usingstdin=p1.stdout
there are now two processes connected to the pipep1.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
sop2.stdin
is the only process attached to that pipe, this way ifp2
ends andp1
writes additional data to stdout, it will receive a SIGPIPE since there are no longer any processes attached to that pipe.好的,我明白了。
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?