我在Python27中遇到了close_fds的问题,因此在进行了一些研究之后,我发现了这个example:

from subprocess import Popen, PIPE, STDOUT
p1 = Popen(['cat'], stdin=PIPE, stdout=PIPE)
p2 = Popen(['grep', 'a'], stdin=p1.stdout, stdout=PIPE)
p1.stdin.write("aaaaaaaaaaaaaaaa\n")
p1.stdin.close()
p2.stdout.read()

我的问题是我不明白为什么p1.stdin保持打开状态。 p1不是p2的子级,因此p2不应继承任何p1资源,除非已明确传递了p1.stdout。此外,为什么在close_fds=True中设置p2可以解决此问题? Here是这样写的:



因此,即使我能够理解p1p2之间的继承,但p1.stdin也不应该关闭close_fds=True,因为它是标准输入(1)。

最佳答案

由于p1p2是 sibling ,因此在它们对应的进程之间没有直接进行继承。

但是,请考虑父级将其视为p1.stdin的文件描述符,该文件描述符由p1继承并重定向到其stdin。该文件描述符存在于父进程中(具有0、1或2以外的数字-您可以通过打印p1.stdin.fileno()进行验证),并且它必须存在,因为我们打算从父进程写入它。该文件描述符是由p2意外继承并保持打开的状态。

当一个打开的文件被多个文件描述符引用时(与p1.stdin一样),仅当所有描述符关闭时,它才会关闭。这就是为什么必须同时关闭p1.stdin并将close_fds传递给p2的原因。 (如果您手动实现了生成代码,则只需在第二个fork()之后关闭文件描述符即可。)

10-07 19:38
查看更多