Ответ 1
Я не уверен, что для этого вам нужен поток. Похоже, вы просто хотите запустить процесс, поэтому загляните в модуль subprocess
.
Я пытаюсь выяснить, как запустить процесс в фоновом потоке в Django. Я новичок в Django и потоках, поэтому, пожалуйста, несите меня, если я неправильно использую терминологию.
Вот код, который у меня есть. В принципе, мне бы хотелось, чтобы start_processing
начинался, как только срабатывала функция success
. Однако start_processing
- это функция, которая может занять несколько минут или не работать (зависит от внешней службы, над которой у меня нет контроля), и я не хочу, чтобы пользователю приходилось ждать, чтобы она завершилась успешно перед представлением представления. ( "Успех", насколько это возможно, не зависит от результата start_processing
, я единственный человек, которому нужно беспокоиться, если он терпит неудачу.)
def success(request, filepath):
start_processing(filepath)
return render_to_response('success.html', context_instance = RequestContext(request))
Из Googling, который я сделал, большинство людей полагают, что фоновые потоки не используются в Django, и вместо этого задача cron более подходит. Но мне бы очень хотелось, чтобы start_processing
начинался, как только пользователь добирался до функции успеха, а не ожидал, пока работа cron запустится. Есть ли способ сделать это?
Я не уверен, что для этого вам нужен поток. Похоже, вы просто хотите запустить процесс, поэтому загляните в модуль subprocess
.
Если вам действительно нужен быстрый взлом, просто запустите процесс, используя subprocess.
Но я бы не рекомендовать нерест процесса (или даже потока), особенно если ваш веб-сайт является общедоступным: в случае высокой нагрузки (что может быть "естественным" или результатом тривиальная атака DoS), вы будете создавать множество процессов или потоков, которые в конечном итоге будут использовать все ваши системные ресурсы и убить ваш сервер.
Вместо этого я бы рекомендовал использовать сервер заданий: я использую Celery (с Redis в качестве бэкэнд), это очень просто и отлично работает. Вы можете проверить многие другие серверы заданий, такие как RabbitMQ или Gearman. В вашем случае сервер задания может быть переполнен: вы можете просто запустить Redis и использовать его в качестве легкого сервера сообщений. Здесь пример, как это сделать.
Приветствия
Если кто-то действительно хочет запустить другой поток
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 на всех ваших серверах - это не очень хорошая идея. Тогда не будет способа запустить отдельный процесс на каждом сервере. Для обработки этого случая вам понадобятся потоки. Примером могут служить операции с файловой системой. Это не очень вероятно, хотя и лучше использовать сельдерей с длительными процессами.
Используйте разумно.
IIUC. Проблема заключается в том, что для процесса веб-сервера могут не нравиться дополнительные длительные потоки, они могут убивать/запускать серверные процессы по мере увеличения спроса и т.д. и т.д.
Вероятно, вам лучше взаимодействовать с внешним процессом обслуживания для этого типа обработки, а не внедрять его в процесс wsgi/fastcgi веб-сервера.
Если единственное, что вы отправляете, это путь к файлу, для этого приложения-приложения должно быть довольно легко написать.