Python close_fds不清楚

时间:2013-11-13 09:36:13

标签: python process parent-child file-descriptor

我在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写成:

  

如果close_fds为true,则在执行子进程之前将关闭除0,1和2之外的所有文件描述符。

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

1 个答案:

答案 0 :(得分:11)

由于p1p2是兄弟姐妹,因此不会直接在相应的进程之间进行继承。

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

当多个文件描述符引用打开的文件时(如p1.stdin的情况),只有在所有关闭描述符时才会关闭它。这就是为什么有必要关闭p1.stdin close_fds传递给p2。 (如果您手动实现了产生代码,则只需在第二个fork()之后关闭文件描述符。)