开发者

closing stdout of piped python subprocess

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?


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.


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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜