python - Django 中的线程在生产环境中不起作用

标签 python django multithreading amazon-ec2

我的 Django views.py 中有一个函数,看起来像这样。

def process(request):
form = ProcessForm(request.POST, request.FILES)
if form.is_valid():
    instance = form.save(commit=False)
    instance.requested_by = request.user
    instance.save()
    t = threading.Thread(target=utils.background_match, args=(instance,), kwargs={})
    t.setDaemon(True)
    t.start()
    return HttpResponseRedirect(reverse('mart:processing'))

在这里,我试图在提交 ProcessForm 时在单独的线程中调用函数“background_match”。由于此线程需要一些时间才能完成,我将用户重定向到另一个名为“mart:processing”的页面。

我面临的问题是它在我的本地机器上一切正常,但在作为 AWS EC2 实例的生产服务器上不起作用。线程根本不启动。 background_match 函数中有一个 for 循环,它不会向前移动。

但是,如果我刷新 (CTRL + R)“mart:processing”页面,它会移动 1 或 2 次迭代。因此,要运行由 1000 次迭代组成的完整循环,我需要刷新页面 1000 次。如果在 100 次迭代之后我没有刷新页面,它会卡在那个点并且不会移动到第 101 次迭代。请帮忙!

最佳答案

错误的架构。 Django 和其他网络应用程序应该像这样生成线程。正确的方法是使用任务队列创建异步任务。 django 最流行的任务队列恰好是 Celery .

mart:processing 页面随后应检查异步结果以确定任务是否已完成。粗略的草图如下。

from celery.result import AsynResult
from myapp.tasks import my_task

...
if form.is_valid():
    ...
    task_id = my_task()
    request.session['task_id']=task_id
    return HttpResponseRedirect(reverse('mart:processing'))
    ...

在下一页

task_id = request.session.get('task_id')
if task_id:
    task = AsyncResult(task_id)

关于python - Django 中的线程在生产环境中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44126586/

相关文章:

python - 如何使用方法更改类属性?

django - 如何查看 channel 消费者引发的异常

multithreading - 使用MSBuild并行构建的问题

multithreading - 条件变量真的需要另一个变量吗?

linux - 如何为 3 个不同的事件(信号量、pthread 条件和阻塞套接字接收)阻塞单个线程?

Python 找不到已安装的 flask 包

python - 将两个列表合并为一个列表,其中它们共享相同的值,并使用列表理解删除重复项

python - 无法在基于 Django 的基本网站上显示 mysql 数据库

python - Django 和 DB 错误 "Column ' id'指定了两次”

django - 额外字段 Django 注册表单