python - 子进程 block Django View

标签 python django subprocess

我在从 View 调用 subprocess.Popen 时遇到问题: 在子进程完成之前,不会显示调用 subprocess.Popen 的 View 。 服务器立即发送“200 OK”,但不发送页面内容。

我的问题是:这是 Django 开发服务器的限制还是我做错了?

服务器不会完全挂起,因为其他 View 可以同时处理。

已经有 a few questions on that topic谷歌给出 a few other threads , 但我找不到我的问题的明确答案。

我相信这不是 python 问题,因为此命令会立即终止:

python -c 'import subprocess; print subprocess.Popen(["/bin/sleep", "10"]).pid'

如何重现

创建测试项目和应用:

cd /tmp
django-admin.py startproject django_test
cd django_test
./manage.py startapp subprocess_test

将 urls.py 和 subprocess_test/views.py 替换为:

  • urls.py:

    从 django.conf.urls.defaults 导入 *

    urlpatterns = patterns('',
    (r'^hello$', 'subprocess_test.views.hello'),
    (r'^start$', 'subprocess_test.views.start'),
    )

  • subprocess_test/views.py

    从 django.http 导入 HttpResponse

    导入子进程

    定义你好(请求):
    返回 HttpResponse('Hello world!')

    定义开始(请求):
    subprocess.Popen(["/bin/sleep", "10"])
    return HttpResponse('开始完成')

测试一下:

./manage.py runserver 0.0.0.0:8000

转到 http://127.0.0.1:8000/hellohttp://127.0.0.1:8000/start

测试结果

“start”需要 10 秒才能加载,而“hello”可以在此期间加载。 比如我得到这样一条日志:

[01/Feb/2011 07:20:57] "GET /hello HTTP/1.1" 200 12
[01/Feb/2011 07:21:01] "GET /start HTTP/1.1" 200 10
[01/Feb/2011 07:21:01] "GET /hello HTTP/1.1" 200 12
[01/Feb/2011 07:21:02] "GET /hello HTTP/1.1" 200 12

使用 wget:

wget http://127.0.0.1:8000/start
--2011-02-01 14:31:11-- http://127.0.0.1:8000/start
Connecting to 127.0.0.1:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: `start'

[           <=>                           ] 10          --.-K/s   in 9,5s    

2011-02-01 14:31:21 (1,05 B/s) - « start » saved [10]

最佳答案

看起来您并不关心系统调用的结果是什么,所以我假设您正在尝试进行某种离线(或后台)处理。

我建议采用一种更简洁的方式来处理它,而不是直接执行程序。使用排队系统,例如 Gearman排队处理任务,然后有一个单独的工作人员从队列中消费项目。

这样做的好处是可以在出现大流量高峰时保护您的服务器,因此您不会在每次向该 View 发出请求时都 fork 一个进程。您可以根据自己的决定,尽可能慢或尽可能快地消耗元素,而不受流量的影响。

交通可能不是问题,但我个人认为这也是一个更清洁的设计决策。

关于python - 子进程 block Django View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4863405/

相关文章:

python - 实时读取/写入子进程标准输入/标准输出

python - 在python中将 float 写入csv——截断错误

python - 使用变量初始化解释器

javascript - Django 脆皮表单添加 javascript

python - 测试 Django 查询集 : self. assertListEqual vs self.assertQuerysetEqual

django - Nginx 403 禁止提供大图像

python - 如何检查子进程是否正确终止?

python - 在 PySide/PyQt 中使用 drawPolyline 制作动画波

python - Pandas 数据帧转置,to_csv

Python 子进程在一定数量的数据后失败