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
;
中使用以下参数
close_fds=True
- 将
stdin
、stdout
和stderr
设置为subprocess.PIPE
或subprocess.DEVNULL
。
第一个关闭除 stdin、stdout 和 stderr 之外的所有文件句柄。 (2) 下列出的参数可以解决这些问题。
我有一个由三个进程组成的链:进程 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
;
close_fds=True
- 将
stdin
、stdout
和stderr
设置为subprocess.PIPE
或subprocess.DEVNULL
。
第一个关闭除 stdin、stdout 和 stderr 之外的所有文件句柄。 (2) 下列出的参数可以解决这些问题。