Отказ от ответственности : я знаю, что есть несколько похожих вопросов по SO. Я думаю, что прочитал большинство, если не все из них, но не нашел ответа на свой настоящий вопрос (см. Позже).
Я также знаю, что использование сельдерея или других асинхронных систем очередей - это лучший способ для выполнения долгосрочных задач или, по крайней мере, использование сценария, управляемого cron. Есть также документ mod_wsgi о процессах и потоках , но я не уверен, что все понял правильно.
Вопрос:
Каковы точные риски / проблемы, связанные с использованием решений, перечисленных ниже? Является ли какой-либо из них жизнеспособным для длительных задач (хорошо, хотя сельдерей лучше подходит)?
Мой вопрос на самом деле больше о понимании внутренностей wsgi и python / django, чем о поиске лучшего общего решения. Проблемы с блокировкой потоков, небезопасным доступом к переменным, обработкой зомби и т. Д.
Скажем так:
- мой "long_process" делает что-то действительно безопасное. даже если это не помогает, мне все равно.
- питон> = 2,6
- Я использую mod_wsgi с apache (что-нибудь изменится с uwsgi или gunicorn?) В режиме демона
mod_wsgi conf:
WSGIDaemonProcess NAME user=www-data group=www-data threads=25
WSGIScriptAlias / /path/to/wsgi.py
WSGIProcessGroup %{ENV:VHOST}
Я полагал, что это опции, доступные для запуска отдельных процессов (в широком смысле) для выполнения длительной задачи при быстром возвращении ответа пользователю:
os.fork
import os
if os.fork()==0:
long_process()
else:
return HttpResponse()
подпроцесс
import subprocess
p = subprocess.Popen([sys.executable, '/path/to/script.py'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
(где сценарий может быть командой manage.py)
тема
import threading
t = threading.Thread(target=long_process,
args=args,
kwargs=kwargs)
t.setDaemon(True)
t.start()
return HttpResponse()
Примечание.
Из-за Глобальной блокировки интерпретатора в CPython только один поток может выполнять код Python одновременно (даже если некоторые ориентированные на производительность библиотеки могут преодолеть это ограничение). Если вы хотите, чтобы ваше приложение лучше использовало вычислительные ресурсы многоядерных машин, рекомендуется использовать многопроцессорность. Тем не менее, многопоточность по-прежнему является подходящей моделью, если вы хотите запускать несколько задач, связанных с вводом / выводом одновременно.
Основной поток быстро вернется (httpresponse). Будет ли порожденная длинная нить блокировать wsgi делать что-то еще для другого запроса ?!
многопроцессорная
from multiprocessing import Process
p = Process(target=_bulk_action,args=(action,objs))
p.start()
return HttpResponse()
Это должно решить проблему параллелизма потоков, не так ли?
Так что вот варианты, которые я мог придумать. Что будет работать, а что нет и почему?