如何从Django视图启动长时间运行的进程?

16 投票
4 回答
8434 浏览
提问于 2025-04-15 15:21

我需要从Django的视图中启动一个可能需要几个小时才能完成的过程。我不需要知道这个过程的状态,也不需要和它进行沟通,只希望在启动这个过程后,视图能立即跳转到其他地方。

我试过使用 subprocess.Popen,在新的 threading.Thread 中使用它,或者使用 multiprocessing.Process。但是,父进程总是会挂起,直到子进程结束。唯一“差不多”能做到这一点的方法是使用fork。不过,这样做显然不好,因为它会留下一个僵尸进程,直到父进程结束。

这就是我在使用fork时想要实现的:

if os.fork() == 0:
    subprocess.Popen(["/usr/bin/python", script_path, "-v"])
else:
    return HttpResponseRedirect(reverse('view_to_redirect'))

那么,有没有办法从Django视图中启动一个完全独立的进程,而且不会造成太多问题呢?还是说我做错了什么?

4 个回答

2

这是一个很不错的库,你可以用它来完成这个任务。

5

首先,试着用cron来处理你的任务,就像shanyu早先提到的那样。

如果这不适合你,那就可以试试CeleryProject,这是一个用于Django的任务队列。它工作时需要用到RabbitMQ。这里有一个简单的概述,可以帮助你了解如何基本使用它。

10

我不知道这是否适合你的情况,不过我可以分享一下我的做法:我使用了一个任务队列(通过一个django模型);当视图被调用时,它会在任务里添加一条新记录,然后开心地进行重定向。接着,这些任务会由cron定期执行,而不依赖于django。

补充一下:cron会调用相关的(自定义的)django命令来执行这个任务。

撰写回答