我正在阅读子进程模块部分中有关 Popen 类的 Python 文档,我遇到了以下代码:
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 文档还指出
“启动 p2 后的 p1.stdout.close() 调用非常重要,如果 p2 在 p1 之前退出,则 p1 可以收到 SIGPIPE。
为什么必须先关闭 p1.stdout,然后才能收到 SIGPIPE,如果我们已经关闭了 p1.stdout,那么 p1 如何知道 p2 在 p1 之前退出?
SIGPIPE
是一个将被发送的信号,如果dmesg
尝试写入封闭的管道。这里,dmesg
最终以two要写入的目标、您的 Python 进程和grep
过程。
那是因为subprocess
克隆文件句柄(使用os.dup2()功能)。配置p2
to use p1.stdout
触发一个os.dup2()
要求操作系统复制管道文件句柄的调用;副本用于连接dmesg
to grep
.
有两个打开的文件句柄dmesg
标准输出,dmesg
从未被给予SIGPIPE
信号如果仅one其中一些很早就关门了,所以grep
关闭永远不会被检测到。dmesg
将不必要地继续产生产出。
所以通过关闭p1.stdout
立即,您确保唯一剩余的文件句柄读取dmesg
标准输出是grep
进程,如果该进程退出,dmesg
收到一个SIGPIPE
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)