我在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是这样写的:因此,即使我能够理解
p1
和p2
之间的继承,但p1.stdin
也不应该关闭close_fds=True
,因为它是标准输入(1)。 最佳答案
由于p1
和p2
是 sibling ,因此在它们对应的进程之间没有直接进行继承。
但是,请考虑父级将其视为p1.stdin
的文件描述符,该文件描述符由p1
继承并重定向到其stdin
。该文件描述符存在于父进程中(具有0、1或2以外的数字-您可以通过打印p1.stdin.fileno()
进行验证),并且它必须存在,因为我们打算从父进程写入它。该文件描述符是由p2
意外继承并保持打开的状态。
当一个打开的文件被多个文件描述符引用时(与p1.stdin
一样),仅当所有描述符关闭时,它才会关闭。这就是为什么必须同时关闭p1.stdin
并将close_fds
传递给p2
的原因。 (如果您手动实现了生成代码,则只需在第二个fork()
之后关闭文件描述符即可。)