在我的一个Django视图中,我需要启动一个可能需要几分钟才能完成的异步作业。由于Celery +消息队列对于此任务来说太过分了,我使用subprocess.Popen创建了一个子进程,如下所示:
args = ['python', SCRIPT_PATH, "&"];
try:
subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Async call
except:
pass
return HttpResponse("Job submitted")
我使用nginx + gunicorn来运行我的django应用程序。当我启动服务器并打开shell会话时,上面的代码工作正常。 但是当我关闭shell会话时,代码停止工作并挂起在Popen行中。
我想这是关于stdout / stderr参数,但我不知道如何更改它以使其工作。
====== EDIT ===========
这就是我在脚本中所做的:我使用selenium webdriver + phantomjs加载网页并提交表单,在此过程中,selenium或phantomjs写入标准输出或标准错误。当我在一个shell中启动gunicorn,然后关闭shell会话时,selenium或phantom的写入失败。 当我启动gunicorn时,其输出重定向到这样的文件:
gunicorn app.wsgi > /tmp/gunicorn.log &
问题消失了。
答案 0 :(得分:3)
虽然我无法确定Popen线路阻塞的原因,但我可以提出一个替代方案。另外,我不确定你需要“&”选项也是。
您可以将NamedTemporaryFiles用于stdout和stderr错误流,例如
from tempfile import NamedTemporaryFile
output = NamedTemporaryFile(delete=False)
error = NamedTemporaryFile(delete=False)
Popen(args, stdout=output, stderr=error)
这不会阻止。我认为你已经完成了Popen完成后要做的事情。
Popen文档有关于PIPE对象的警告。我在这里粘贴它是为了完整
The data read is buffered in memory, so do not use this method if the data size is large or unlimited.