LINUX.ORG.RU

Python 3 Потоки/Очереди задач.

 , ,


0

3

Добрый день. Возникла сейчас необходимость писать API, при запросе к которому необходимо выполнять некоторые тяжелые вычисления. На выполнение одного уходит где-то 20-40 секунд. После результат отправляется по другим каналам (или в БД). Что лучше для такого использовать? Понятно, что асинхронщина не вариант из-за CPU work. Потоки? Просто тут GIL. Как вариант, субпроцессы. По сути, работа - запуск стороннего bash скрипта и получение результатов от него, так что субпроцессы должны сработать хорошо. Может для такого какие очереди задач будут лучше? Подумываю насчет Celery.

Я хотеть асинхроньщину, но не асинхроньщину,а ты забавный

anonymous
()

Один процесс - один процессор. Смотришь сколько у тебя есть процессоров и решаешь нужны ли тебе очереди. Для очередей celery избыточен, проще использовать rq.

В некоторых случаях, чтобы не заморачиваться с менеджментом процессов, проще использовать supervisor для запуска нескольких скриптов-воркеров.

Jopich1
()
Последнее исправление: Jopich1 (всего исправлений: 1)

гляньте dask.distributed, вроде проще celery

anonymous
()
Ответ на: комментарий от crarkie

У asyncio есть механизмы работы с внешними воркерами. Выше даже даже ссылку дали.

Но не так всё однозначно, конечно, ты бы лучше задачу чуть подробнее описал.

WitcherGeralt ★★
()
Ответ на: комментарий от WitcherGeralt

Но не так всё однозначно, конечно, ты бы лучше задачу чуть подробнее описал.

Запускается ffmpeg для перекодирования (короткий ролик), после полученный файл необходимо переслать по email.

crarkie
() автор топика

Понятно, что асинхронщина не вариант из-за CPU work

Кстати, не знаю как сейчас, но в официальной доке к asyncio изначально был пример то ли с факториалом, то ли с числами Фиббоначи.

vvn_black ★★★★★
()
Ответ на: комментарий от crarkie

А само API что-то ещё делает, кроме как этот запрос принимает?

В зависимости от уровня проекта и нагрузки, можно как на коленочке сделать, просто всё в одном сервисе, за счёт воркеров на сабпроцессах с помощью asyncio. Так и по-взрослому с очередью и гарантированной доставкой, в которую тонкое API будет только задачи складывать, а с другой стороны сервис будет кодировать и отправлять имейл, затем подтверждать выполнение таска. Можно добавить даже третий сервис для отправки имейлов, который так же через очередь будет работать.

WitcherGeralt ★★
()
Последнее исправление: WitcherGeralt (всего исправлений: 1)

Asyncio, celery, rq... человеку, скорее всего, нужен Popen(), а потом просто проверять «p.poll() is not None» в свободное от суеты время. Если работников много, то да, можно начинать думать про celery/rq/etc.

byko3y ★★★★
()
Ответ на: комментарий от WitcherGeralt

В зависимости от уровня проекта и нагрузки, можно как на коленочке сделать, просто всё в одном сервисе, за счёт воркеров на сабпроцессах с помощью asyncio.

Думаю так и сделаю. По факту задача - приходит запрос вместе с файлом. Файл этот сохраняется на сервере, далее вызывается bash скрипт. Он завершается, мы получаем готовый файл. Его пересылаем на email, все. Уровень проекта небольшой, нагрузка маленькая-средняя. Скорее хочется понять, как сделать, чтобы долго не мучаться с этим, но при этом и не совсем велосипед.

crarkie
() автор топика

при запросе к которому необходимо выполнять некоторые тяжелые вычисления

Ну это сразу напрашивается вынести из питона в модуль на C.

А так явно напрашивается очередь и отдельный демон который её разгребает, а он уже может хоть форкаться, хоть сам себя через subprocess запускать, хоть просто быть запущенным несколько раз.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

Ну это сразу напрашивается вынести из питона в модуль на C.

Зачем, если по факту эти вычисления выполняет bash скрипт, который банально вызывает ffmpeg?

crarkie
() автор топика
Ответ на: комментарий от crarkie

Файл этот сохраняется

вызывается bash скрипт. Он завершается, мы получаем готовый файл

вычисления проводятся не питоном в вашем случае, значит ваши питоновские потоки будут только ждать, но не делать работы. гил им не помешает. у вас нет никакой проблемы.

mxrd2
()
Ответ на: комментарий от crarkie

Я не обратил на это внимания после «некоторых тяжелых вычислений» и «CPU work». Конечно же никакой CPU work тут нету и асинхронщина подходит как нельзя лучше. Очередь нужна чтобы не потерять задачи, я бы её сделал прямо в базе чтобы не плодить сущности.

slovazap ★★★★★
()
Ответ на: комментарий от hakavlad

import threading

Потоки сядут на одно ядро и не помогут в утилизации ЦПУ.

Ему не нужно считать ничего в потоке - ему нужно запустить и ждать баш-скрипт. Именно для ввода-вывода потоки сделаны в питоне.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

ОП же про тяжелые вычисления спрашивал, а не про io.

hakavlad ★★★
()

работа - запуск стороннего bash скрипта и получение результатов

На выполнение одного уходит где-то 20-40 секунд

Ничего не понимаю. Опишите задачу еще раз, пожалуйста. В чем заключается работа, почему запуск скрипта 40 секунд вместо 1 ms и зачем тут субпроцессы.

hakavlad ★★★
()

Вот вам функция запуска потока из моего демона.

from threading import Thread

def go(func, *a):
    """ run func in new thread
    """
    t1 = monotonic()
    th = Thread(target=func, args=a)
    th_name = th.getName()
    if debug_threading:
        log('Starting {}'.format(th_name))
    try:
        th.start()
        t2 = monotonic()
        if debug_threading:
            log('{} has started in {} ms'.format(
                th_name, round((t2 - t1) * 1000, 1)))
    except RuntimeError:
        if debug_threading:
            log('RuntimeError: cannot start {}'.format(th_name))

go(function, agrument)  # функция запустится в отдельном потоке

Как раз для запуска внешних команд, чтоб основной поток программы не останавливался во время запуска внешней команды (особенно актуально во время интенсивного своппинга, даже запуск echo «foo» при этом на несколько секунд может остановить основной поток, а поток же рожается за миллисекунды и помогает основному потоку не останавливаться).

hakavlad ★★★
()

и да, трединг оч мало оперативы потребляет в отличие от процессинга. asyncio тоже тяжелый импорт.

hakavlad ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.