Python; popen 不通过 std*

Python; popen do not pass std*

我有一个由三个进程组成的链:进程 A 调用 B 生成 C,然后 B 死亡。我们可以在两个系统A和C之间称B为"bridge"。

我想确保 C 不会继承 A 打开的任何文件描述符,以防止僵尸,我目前正在观察(有时 A 调用 B 杀死 C,此后,我看到已失效的 C进程挂起,但我不知道 A 中的代码是什么样的)。

为确保此问题不是由于 stdin/out/err 被传递, 我目前正在 B

中执行以下操作
def _close_fds(): #workaround carstens bug
    for fd in [0, 1, 2]:
        try:
            os.close(fd)
        except Exception:
            logger.info("File descriptor was not open")

...
_close_fds() #make sure there are no open file descriptors for the chile to enherit
pid = subprocess.Popen([_ROOT_PATH  + "something.py"]).pid
...

有更好的方法吗?

os 模块提供了一个很好的函数,os.closerange(),它将在一次调用中为您完成:

os.closerange(0, 3)

如果你正在寻找幻影打开的文件,我会更高一点以防万一:

os.closerange(0, 10)

要找出您实际需要关闭的内容,您可以检查 /proc/self/fd 您的进程打开的文件描述符列表(如果您的 OS 支持它),and/or 使用 psutil. See the answers to this question 中的 open_files() 方法获得更多想法。

当您从 B 启动进程 C,并且不希望它继承任何文件句柄时,请在 subprocess.Popen;

中使用以下参数
  1. close_fds=True
  2. stdinstdoutstderr设置为subprocess.PIPEsubprocess.DEVNULL

第一个关闭除 stdinstdoutstderr 之外的所有文件句柄。 (2) 下列出的参数可以解决这些问题。