Django:在后台线程中启动一个进程?
Posted
技术标签:
【中文标题】Django:在后台线程中启动一个进程?【英文标题】:Django: start a process in a background thread? 【发布时间】:2011-01-23 18:45:44 【问题描述】:我正在尝试研究如何在 Django 的后台线程中运行进程。我对 Django 和线程都是新手,所以如果我使用的术语有误,请多多包涵。
这是我的代码。基本上我希望start_processing
在success
函数被触发后立即开始。但是start_processing
是一种很容易花费几分钟或失败的功能(它依赖于我无法控制的外部服务),我不希望用户必须等待它成功完成在视图渲染之前。 (就他们而言,“成功”并不取决于start_processing
的结果;如果失败,我是唯一需要担心的人。)
def success(request, filepath):
start_processing(filepath)
return render_to_response('success.html', context_instance = RequestContext(request))
根据我所做的谷歌搜索,大多数人建议在 Django 中不使用后台线程,而是使用 cron 作业更合适。但我非常希望start_processing
在用户到达成功功能后立即开始,而不是等到 cron 作业运行。有没有办法做到这一点?
【问题讨论】:
重复:***.com/questions/844570/…,等等。 其中大部分也很有帮助:***.com/search?q=%5Bdjango%5D+process 复制:***.com/questions/1619397/…,***.com/questions/219329/… 抱歉重复了 - 正如我所想的那样,我弄错了术语;我在寻找 django+thread,而不是 django+process。 一般在计算中,进程是在操作系统中执行的计算机程序,可以包含一个或多个线程。说“在后台线程中运行进程”令人困惑,因为进程包含线程,而不是相反。我认为您使用的是更一般意义上的词处理。 【参考方案1】:我不确定你是否需要一个线程。听起来您只是想生成一个进程,因此请查看 subprocess
模块。
【讨论】:
【参考方案2】:IIUC,这里的问题是网络服务器进程可能不喜欢额外的长时间运行的线程,它可能会随着需求的上升和下降等原因杀死/生成服务器进程,等等。
您可能最好通过与外部服务进程通信来进行此类处理,而不是将其嵌入到网络服务器的 wsgi/fastcgi 进程中。
如果您发送的唯一内容是文件路径,那么编写该服务应用程序应该很容易。
【讨论】:
【参考方案3】:如果您真的需要快速破解,只需使用 subprocess 启动一个进程。
但我不建议生成一个进程(甚至是一个线程),特别是如果您的网站是公开的:在高负载的情况下(这可能是“自然的”或微不足道的DoS 攻击),您将产生许多进程或线程,最终会耗尽您的所有系统资源并杀死您的服务器。
我会建议使用作业服务器:我使用Celery(以Redis 作为后端),它非常简单并且效果很好。您可以查看许多其他作业服务器,例如 RabbitMQ 或 Gearman。在您的情况下,作业服务器可能有点矫枉过正:您可以简单地运行 Redis 并将其用作轻量级消息服务器。这是an example 的操作方法。
干杯
【讨论】:
【参考方案4】:如果有人真的想运行另一个线程
def background_process():
import time
print("process started")
time.sleep(100)
print("process finished")
def index(request):
import threading
t = threading.Thread(target=background_process, args=(), kwargs=)
t.setDaemon(True)
t.start()
return HttpResponse("main thread content")
这将首先返回响应,然后将“进程完成”打印到控制台。所以用户不会面临任何延迟。
使用 Celery 绝对是更好的解决方案。但是,对于服务器有限的非常小的项目等,安装 Celery 可能是不必要的。
您可能还需要在大型项目中使用线程。因为在所有服务器上运行 Celery 并不是一个好主意。那么就没有办法在每台服务器上运行一个单独的进程。您可能需要线程来处理这种情况。文件系统操作可能就是一个例子。不过这不太可能,最好还是将 Celery 用于长时间运行的进程。
明智地使用。
【讨论】:
这在本地工作正常,但通过 UWSGI 对我不起作用以上是关于Django:在后台线程中启动一个进程?的主要内容,如果未能解决你的问题,请参考以下文章