解释Python子进程模块的示例管道
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
信号。如果你不关闭这个文件,它就永远不会到达零。)