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

Posted

技术标签:

【中文标题】Django:在后台线程中启动一个进程?【英文标题】:Django: start a process in a background thread? 【发布时间】:2011-01-23 18:45:44 【问题描述】:

我正在尝试研究如何在 Django 的后台线程中运行进程。我对 Django 和线程都是新手,所以如果我使用的术语有误,请多多包涵。

这是我的代码。基本上我希望start_processingsuccess 函数被触发后立即开始。但是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:在后台线程中启动一个进程?的主要内容,如果未能解决你的问题,请参考以下文章

gunicorn结合django启动后台线程

Django异步任务线程池

什么是 Daemon 线程?它有什么意义?

用于较长任务的后台线程

关于C# WPF线程后台运行的

在同一个后台线程上运行 FMDB 进程?