在我的一个 Django View 中,我需要启动一个可能需要几分钟才能完成的异步作业。由于 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 session 时,上面的代码工作正常。 但是当我关闭 shell session 时,代码停止工作并卡在 Popen 行。
我猜这是关于 stdout/stderr 参数,但我不知道如何更改它以使其工作。
=========编辑===========
这是我在脚本中所做的:我使用selenium webdriver+phantomjs加载网页并提交表单,在此过程中,selenium或phantomjs写入标准输出或标准错误。当我在 shell 中启动 gunicorn,然后关闭 shell session 时,selenium 或 phantom 的写入失败。 当我启动 gunicorn 并将其输出重定向到这样的文件时:
gunicorn app.wsgi > /tmp/gunicorn.log &
问题解决了。
最佳答案
虽然我无法根据您提供的详细信息确定 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 对象的警告。为了完整起见,我将其粘贴在这里
读取的数据缓存在内存中,如果数据量很大或没有限制,请不要使用此方法。
关于python - 为什么在 Django View 中使用 Popen 会挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24979333/