Python 子进程在什么情况下会收到 SIGPIPE?

2023-12-10

我正在阅读子进程模块部分中有关 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(使用前将#替换为@)

Python 子进程在什么情况下会收到 SIGPIPE? 的相关文章

随机推荐