解释Python子进程模块的示例管道

8 投票
1 回答
3141 浏览
提问于 2025-04-16 17:53

Python的子进程模块中有一部分提到要把

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]

第三行的注释解释了为什么要调用close函数,但没有说明这样做的意义。对我来说,这个意义不太明白。在调用communicate方法之前,如果不关闭p1.stdout,是否会阻止任何输出通过管道发送?(显然不会,我试过运行代码,运行得很好)。为什么必须调用close才能让p1接收到SIGPIPE信号?这个close到底是什么样的,为什么它又不是真正的关闭?它到底关闭了什么呢?

请把这个问题当作学术性的问题,我只是想更好地理解这些内容,并没有其他目的。

1 个回答

11

你在p1.stdout中关闭了父进程的输出,这样就只剩下dmesg这个进程还打开着这个文件。 如果你不这样做,即使dmesg关闭了它的输出,你的进程仍然会保持这个文件打开,这样就不会产生SIGPIPE信号。 (操作系统基本上会保持一个引用计数,当计数到达零时就会生成SIGPIPE信号。如果你不关闭这个文件,它就永远不会到达零。)

撰写回答