Disclaimer:我知道网上有几个类似的问题.我想我已经读了大部分(如果不是全部),但没有找到我真正问题的答案(见后文). 我还知道使用Celery 或其他异步队列系统是实现长时间运行任务的最佳方式-或者至少使用cron管理的脚本.也有mod_wsgi doc about processes and 螺纹个,但我不确定我都记对了.

问题是:

使用下面列出的解决方案具体涉及哪些风险/问题?它们中有没有适合长时间运行任务的(好的,尽管Celery 更适合)? 我的问题实际上更多的是关于理解WSGI和python/Django的内部 struct ,而不是寻找最佳的整体解决方案.阻塞线程、不安全访问变量、僵尸处理等问题.

比如说:

  1. 我的"长进程"正在做一些非常安全的事情.即使失败了,我也不在乎.
  2. python >= 2.6
  3. 我在Apache中使用mod_wsgi(uwsgi或genicorn会有什么变化吗?)在后台进程模式下

MOD_WSGI会议:

WSGIDaemonProcess NAME user=www-data group=www-data 螺纹=25
WSGIScriptAlias / /path/to/wsgi.py
WSGIProcessGroup %{ENV:VHOST}

我认为可以使用这些选项来启动单独的processes(广义的意思是)来执行长时间运行的任务,同时快速向用户返回响应:

操作系统.叉

import os

if 操作系统.叉()==0:
    long_process()
else:
    return HttpResponse()

子流程

import 子流程

p = 子流程.Popen([sys.executable, '/path/to/script.py'], 
                                    stdout=子流程.PIPE, 
                                    stderr=子流程.STDOUT)

(其中脚本很可能是manage.py命令)

螺纹

import threading

t = threading.Thread(target=long_process,
                             args=args,
                             kwargs=kwargs)
t.setDaemon(True)
t.start()
return HttpResponse()

注意:

由于全局解释器锁,在CPython中,一次只能有一个线程执行Python代码(尽管某些面向性能的库可能会克服这个限制).如果您希望应用程序更好地利用多核机器的计算资源,建议您使用多处理.但是,如果希望同时运行多个I/O绑定任务,线程仍然是一种合适的模型.

主线程将快速返回(httpresponse).生成的长线程会阻止wsgi为另一个请求做其他事情吗?!

多处理

from 多处理 import Process

p = Process(target=_bulk_action,args=(action,objs))
p.start()
return HttpResponse()

这应该可以解决线程并发问题,不是吗?


这些就是我能想到的 Select .什么有效,什么无效,为什么?

推荐答案

100

fork将克隆父进程,在本例中,父进程就是您的Django堆栈.因为您只想运行一个单独的python脚本,所以这似乎是一个不必要的inflating .

100

使用subprocess应该是交互式的.换句话说,虽然您可以使用它来有效地派生一个进程,但预计在某个时候,您会在完成时终止它.如果您让其中一个保持运行,Python可能会为您清理干净,但我猜测这实际上会导致内存泄漏.

100

线程是定义的逻辑单元.它们在调用run()方法时开始,在run()方法执行结束时终止.这使得它们非常适合创建将在当前范围之外运行的逻辑分支.但是,正如您所提到的,它们受到全局解释器锁的约束.

100

此模块允许您派生进程,其API类似于threading.你可以说就像类固醇上的线.这些进程不受全局解释器锁的约束,并且它们可以利用多核架构.然而,结果是使用它们变得更加复杂.

因此,您的 Select 实际上取决于线程或进程.如果您可以使用线程,并且它对您的应用程序有意义,那么就使用线程.否则,请使用进程.

Django相关问答推荐

如何根据属性的 Select 对查询集进行排序

使用django直接计算geohash而不创建模型

如何在Django模型mixin字段定义中引用模型名称?

Django-admin 显示decorator 按多列排序

Templatetag 在 Django 4.2 模板 IF 条件中不起作用

错误``Forbidden (403) CSRF 验证失败.请求中止.``` 当try 登录管理员时

源自访问外键关系的模型方法 get_absolute_url 的 django 重复 SQL 查询

当从 fastapi 发送请求时,Django 无法对 Postgres 执行查询

将两个视图重定向到具有不同 url id Django 的一个模板的正确方法

如何在没有此前缀的情况下修复此 django 路径?

如何在 Django 模板视图中显示我的数据?

DeleteView 中的success_message 未显示

django 用一个提交按钮提交两种不同的表单

删除所有表的django命令是什么?

get_or_create() 线程安全吗

django 如何知道已经运行了哪些迁移?

在 django 中获取空查询集的类名

django.core.servers.basehttp.FileWrapper 在 Django 1.9 中消失

Django:在模块中实现 status字段的最佳方式

我将如何package打包和销售 Django 应用程序?