在子进程模块的Python 2.7文档中,我找到了以下代码段:
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]
Run Code Online (Sandbox Code Playgroud)
资料来源:https://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline
我不明白这一行: p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
这里p1.stdout正在关闭.如果p2退出,它如何允许p1接收SIGPIPE?
如果进程尝试写入没有活动进程正在查找的管道,则通常会发送 SIGPIPE 信号。在相当于代码片段的 shell 管道中:
`dmesg | grep hda`
Run Code Online (Sandbox Code Playgroud)
如果grep进程由于某种原因在dmesg完成写入输出之前终止,dmesg则会收到 SIGPIPE 并自行终止。这将是 UNIX/Linux 进程的预期行为 ( http://en.wikipedia.org/wiki/Unix_signal )。
相比之下,在使用 的 Python 实现中subprocess,如果在生成输出完成p2之前退出,则不会发送 SIGPIPE,因为实际上仍然有一个进程在查看管道 - Python 脚本本身(创建和 的p1那个)。更重要的是,脚本查看管道但不消耗其内容 - 结果是管道无限期地保持打开状态并陷入困境。p1p2p1
显式关闭p1.stdout将Python脚本与管道分离,并使其除了p2查看管道之外没有其他进程 - 这样,如果p2确实在之前结束p1,p1则正确获取结束自身的信号,而无需任何人为地保持管道打开。
这是一个替代措辞的解释: http://www.enricozini.org/2009/debian/python-pipes/
| 归档时间: |
|
| 查看次数: |
364 次 |
| 最近记录: |