在什么情况下,Python子进程会获得SIGPIPE? [英] Under what condition does a Python subprocess get a SIGPIPE?

查看:97
本文介绍了在什么情况下,Python子进程会获得SIGPIPE?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在子进程模块部分中阅读有关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]

文档还指出

启动p2之后的p1.stdout.close()调用很重要,如果p2在p1之前退出,则p1才能接收SIGPIPE.

为什么在我们收到SIGPIPE之前必须先关闭p1.stdout,如果已经关闭p1,p1如何知道p2在p1之前退出?

解决方案

SIGPIPE是一个信号,如果dmesg尝试写入封闭的管道,该信号将被发送.在这里,dmesg最终以两个目标写入,即您的Python进程和grep进程.

这是因为subprocess克隆文件句柄(使用 os.dup2()功能).将p2配置为使用p1.stdout会触发一个os.dup2()调用,该调用要求操作系统复制管道文件句柄.副本用于将dmesg连接到grep.

具有两个用于dmesg stdout的打开文件句柄,如果只有一个提前关闭,则不会向dmesg发出SIGPIPE信号,因此将永远不会检测到grep关闭. dmesg会不必要地继续产生输出.

因此,通过立即关闭p1.stdout,可以确保从dmesg stdout读取的唯一剩余文件句柄是grep进程,并且如果该进程要退出,则dmesg会收到SIGPIPE. >

I am reading the the Python documentation on the Popen class in the subprocess module section and I came across the following code:

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 documentation also states that

"The p1.stdout.close() call after starting the p2 is important in order for p1 to receive a SIGPIPE if p2 exits before p1.

Why must the p1.stdout be closed before we can receive a SIGPIPE and how does p1 knows that p2 exits before p1 if we already closed it?

解决方案

SIGPIPE is a signal that would be sent if dmesg tried to write to a closed pipe. Here, dmesg ends up with two targets to write to, your Python process and the grep process.

That's because subprocess clones file handles (using the os.dup2() function). Configuring p2 to use p1.stdout triggers a os.dup2() call that asks the OS to duplicate the pipe filehandle; the duplicate is used to connect dmesg to grep.

With two open file handles for dmesg stdout, dmesg is never given a SIGPIPE signal if only one of them closes early, so grep closing would never be detected. dmesg would needlessly continue to produce output.

So by closing p1.stdout immediately, you ensure that the only remaining filehandle reading from dmesg stdout is the grep process, and if that process were to exit, dmesg receives a SIGPIPE.

这篇关于在什么情况下,Python子进程会获得SIGPIPE?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆