сервере CPU bound функции в ThreadPoolExecutor понятно что быстрее работать не станет, но это же решит проблему с блокировкой ивент лупа? По идеи поток должен отпускать GIL и ивент луп сможет нормально делегировать, ведь так? Или лучше запускать cpu bound в ProcessPoolExecutor?
Решит
Ок, благодарю, а второе решение запускать в ProcessPoolExecutor имеет какое-то преимущество если у меня 1 процесс только? Или наоборот будет чуть медленным из-за выделения ресурсов дополнительных?
Зависит от ситуации: кода, ОС, данных
Я попробовал оба, в случаи с ProcessPoolExecutor 1000 вызовов функции выполняется за 27 сек, а в потоке за 25 сек. Но вот боюсь не будет ли cpu bound мешать ивент лупу..
Разве? Гил же шарится между всеми тредами. Соответственно в одном треде ты уперся в cpu-bound операцию и для работы над ней этот один тред забирает себе общий лок и остальные соответственно стоят. Я так так это понимаю.
Да, но мне казалось что вот этот момент времени он может "убить" такое асинхронное приложение когда все остальные корутины не двигаются по событийному циклу. По крайней мере, если у тебя достаточно большое колличество одномоментных запросов в приложение.
Так в асинке вообще один поток даже без гила
Потоки это вытесняющая многозадачность, а вот asyncio реализует кооперативную. Поэтмоу даже если поток упирается в cpu bound, это не помешает остальным потокам. Но в тасках asyncio/aiohttp это не верно, и cpubound таска заблокирует всех остальных, если принудительно ее на эвейтить.
Как можно заэвейтить cpu bound операцию?
Например обернуть в Future. В питоне прям целая либа встроена просто реалищующая этот паттерн https://docs.python.org/3/library/concurrent.futures.html
Завернуть в future и отправить в ProcessPoolExecutor?
делишь ее на куски и эвейтишь
Нет. Пул сам дает тебе такой "талончик" на получение результата в будущем когда ты даешь ему таск. https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor.submit
Ну технически твоя таска будет выполняться уже не в корутине главного потока, а уйдёт в другой другой (дочерний) процесс. А корутина из главного потока внутри эвент лупа будет эвейтить футуру? Так получается?
Да. Хотя у asyncio есть свой интерфейс для работы с future который предпочтительней, но в целом все работает так.
Ну это делегирование выполнения cpu bound другому процессу с эвейтом результата
Обсуждают сегодня