python 2.7 Popen:"close_fds"有什么作用? [英] python 2.7 Popen: what does `close_fds` do?

查看:182
本文介绍了python 2.7 Popen:"close_fds"有什么作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用Python(2.7)的Web服务器,该服务器使用 Popen 将某些工作委托给子进程:

I have a web server in Python (2.7) that uses Popen to delegate some work to a child process:

url_arg = "http://localhost/index.html?someparam=somevalue"
call = ('phantomjs', 'some/phantom/script.js', url_arg)

imageB64data = tempfile.TemporaryFile()
errordata = tempfile.TemporaryFile()

p = Popen(call, stdout=imageB64data, stderr=errordata, stdin=PIPE)
p.communicate(input="")

我看到间歇性问题,其中发生了一定数量的这些 Popen (大约64个),该进程用尽了文件描述符,无法运行-完全无响应,并且所有如果线程试图打开任何文件或套接字,它们似乎会永远阻塞.

I am seeing intermittent issues where after some number of these Popens have occurred (roughly 64), the process runs out of file descriptors and is unable to function -- it becomes completely unresponsive and all threads seem to block forever if they attempt to open any files or sockets.

(可能相关: phantomjs 子进程将URL调用加载回产生它的服务器中.)

(Possibly relevant: the phantomjs child process loads a URL calls back into the server that spawned it.)

基于此Python错误报告,我相信我需要设置 close_fds = True在服务器进程中所有 Popen 调用上,以减轻文件描述符的泄漏.但是,我不熟悉围绕 exec 进行子处理的机制以及文件描述符的继承,因此许多 Popen 文档以及前面提到的错误报告中的注释对我来说都不是很清楚.

Based on this Python bug report, I believe I need to set close_fds=True on all Popen calls from inside my server process in order to mitigate the leaking of file descriptors. However, I am unfamiliar with the machinery around exec-ing subprocesses and inheritance of file descriptors so much of the Popen documentation and the notes in the aforementioned bug report are unclear to me.

听起来,在执行子流程之前,它实际上会关闭我的流程中的所有打开的文件描述符(包括活动的请求套接字,日志文件句柄等).听起来这绝对比泄漏套接字更好,但仍然会导致错误.

It sounds like it would actually close all open file descriptors (which includes active request sockets, log file handles, etc.) in my process before executing the subprocess. This sounds like it would be strictly better than leaking the sockets, but would still result in errors.

但是,在实践中,当我在Web请求期间使用 close_fds = True 时,它似乎可以正常工作,到目前为止,我还无法构造出它实际上关闭任何其他请求套接字的方案,数据库请求等.

However, in practice, when I use close_fds=True during a web request, it seems to work fine and thus far I have been unable to construct a scenario where it actually closes any other request sockets, database requests, etc.

文档状态:

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

If close_fds is true, all file descriptors except 0, 1 and 2 will be closed before the child process is executed.

所以我的问题是:在多线程Python Web服务器中将 close_fds = True 传递给 Popen 是安全"还是正确"?或者如果其他请求同时执行文件/套接字IO,我应该期望这样做会有副作用吗?

So my question is: is it "safe" and "correct" to pass close_fds=True to Popen in a multithreaded Python web server? Or should I expect this to have side effects if other requests are doing file/socket IO at the same time?

推荐答案

我使用Python 3.2/3.3的 subprocess subprocess32 反向端口尝试了以下测试:/p>

I tried the following test with the subprocess32 backport of Python 3.2/3.3's subprocess:

import tempfile
import subprocess32 as subprocess

fp = open('test.txt', 'w')

fp.write("some stuff")

echoed = tempfile.TemporaryFile()
p = subprocess.Popen(("echo", "this", "stuff"), stdout=echoed, close_fds=True)
p.wait()
echoed.seek(0)

fp.write("whatevs")
fp.write(echoed.read())
fp.close()

我在 test.txt 中得到了一些东西的预期结果.

所以看来 close_fds close 的含义 not 并不意味着在父进程中打开文件(套接字等)执行子进程后将无法使用.

So it appears that the meaning of close in close_fds does not mean that open files (sockets, etc.) in the parent process will be unusable after executing a child process.

同样值得注意的是: subprocess32 在POSIX系统AFAICT上默认为 close_fds = True .在我看来,这并不像听起来那么危险.

Also worth noting: subprocess32 defaults close_fds=True on POSIX systems, AFAICT. This implies to me that it is not as dangerous as it sounds.

这篇关于python 2.7 Popen:"close_fds"有什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆