我在从 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/hello和 http://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/