如果我尝试从pylons控制器生成进程,则服务器在发送回复后不会关闭连接。
假设test.py
是一个长时间运行的进程,那么pylons控制器中的这个方法会创建一个响应,但保持连接打开:
def index(self):
from subprocess import Popen
Popen(["python", "/temp/test.py"])
return "<h1>Done!</h1>"
将Popen
移动到新线程没有帮助。
幸运的是,我找到了一个解决方法:我开始一个新主题并在sleep
之前添加Popen
。如果在发送响应后Popen启动,则连接将正确关闭。
def test(self):
def worker():
import time
time.sleep(5)
from subprocess import Popen
Popen(["python", "/temp/test.py"])
from threading import Thread
Thread(target=worker).start()
return "<h1>Done!</h1>"
任何人都可以解释这种行为吗?我想确定我不会引起奇怪的问题。
我在Windows XP SP3上使用Python 2.5和Pylons 0.9.6.1。
更新:bnonlan的答案绝对是正确的。 Popen
有一个名为close_fds
的参数,可以解决这个问题。在{2.5}版本的subprocess
模块中,Windows上不支持此参数。但是,在Python 2.6版本中,如果不重定向stdin / stdout / stderr,则可以将此参数设置为True
。
def index(self):
# I copied the 2.6 version of subprocess.py into my tree
from python26.subprocess import Popen
Popen(["python", "/temp/test.py"], close_fds=True)
return "<h1>Done!</h1>"
可悲的是,我做想要重定向stdout,所以我需要找到另一个解决方案。此外,这意味着我找到的解决方法可能会阻止其他请求在Popen执行时碰巧运行。这令人不安。