【问题标题】:Why does Popen hang when used in Django view?为什么在 Django 视图中使用 Popen 会挂起?
【发布时间】:2014-09-18 16:50:06
【问题描述】:

在我的一个 Django 视图中,我需要启动一个可能需要几分钟才能完成的异步作业。由于 Celery+message 队列对于这个任务来说是一个过度杀伤,我使用 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 参数,但我不知道如何更改它以使其工作。

=========编辑===========

这是我在脚本中所做的:我使用 selenium webdriver+phantomjs 加载网页并提交表单,在此过程中,selenium 或 phantomjs 写入标准输出或标准错误。当我在 shell 中启动 gunicorn,然后关闭 shell 会话时, selenium 或 phantom 的写入失败。 当我启动 gunicorn 并将其输出重定向到这样的文件时:

gunicorn app.wsgi > /tmp/gunicorn.log &

问题消失了。

【问题讨论】:

    标签: python django asynchronous web


    【解决方案1】:

    虽然我无法根据您提供的详细信息确定 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.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-31
      • 1970-01-01
      • 2021-06-09
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      • 2018-10-12
      • 1970-01-01
      相关资源
      最近更新 更多