python - 为什么在 Django View 中使用 Popen 会挂起?

标签 python django asynchronous web

在我的一个 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/

相关文章:

python - 如何使用 python discord 向机器人所在的每台服务器发送消息

python - 尝试通过 Django REST Framework 创建时出现 ValueError

javascript - Protractor-将 ControlFlow 更改为 async-await

django - 从 form.save 访问请求对象

c# - Async 和 Await 进程中的实体对象

javascript - 使用 async 和 axios 制作天气应用

python - Statsmodels:很难将 ARIMA 预测与原始数据的置信界限叠加

python - SQLAlchemy:如何将数据从旧数据库中的一个表传输到新/不同数据库中的另一个表?

python - Django,来自 USStateField 的完整州名

Django - 没有名为 _sqlite3 的模块