Django:在后台线程中启动进程?

时间:2010-03-04 17:04:32

标签: django multithreading

我正在尝试研究如何在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)) 的结果;如果失败,我是唯一需要担心的人。)

start_processing

从谷歌搜索结果来看,大多数人都认为Django中没有使用后台线程,而cron作业更适合。但是我希望{{1}}一旦用户进入成功函数就开始,而不是等到cron作业运行。有没有办法做到这一点?

4 个答案:

答案 0 :(得分:20)

如果您真的需要快速入侵,只需使用subprocess启动流程。

但我建议产生一个流程(甚至一个线程),特别是如果您的网站是公开的:在高负载的情况下(可能是“自然的”或者是您将会产生许多进程或线程,最终会耗尽所有系统资源并终止您的服务器。

我建议使用作业服务器:我使用DoSCelery作为后端),它非常简单,效果很好。您可以查看许多其他作业服务器,例如RabbitMQ或Gearman。在您的情况下,作业服务器可能有点过分:您可以简单地运行Redis并将其用作轻量级消息服务器。以下是Redis如何执行此操作。

干杯

答案 1 :(得分:9)

如果有人真的想要运行另一个线程

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")

这将首先返回响应,然后将“process finished”打印到控制台。因此用户不会遇到任何延迟。

使用Celery绝对是一个更好的解决方案。但是,对于服务器等有限的非常小的项目,安装Celery可能是不必要的。

您可能还需要在大型项目中使用线程。因为在所有服务器上运行Celery并不是一个好主意。然后,将无法在每个服务器中运行单独的进程。您可能需要线程来处理这种情况。文件系统操作可能是一个例子。虽然这种情况不太可能,但使用长期运行的Celery仍然会更好。

明智地使用。

答案 2 :(得分:5)

我不确定你需要一个线程。听起来你只想生成一个进程,所以请查看subprocess模块。

答案 3 :(得分:3)

IIUC,这里的问题是网络服务器进程可能不喜欢额外长时间运行的线程,它可能会随着需求上升和下降等原因而杀死/生成服务器进程等。

通过与外部服务流程进行此类处理的沟通,您可能会更好,而不是将其嵌入到Web服务器的wsgi / fastcgi流程中。

如果您发送的唯一内容是文件路径,那么编写该服务应用程序应该非常容易。