> Как обойти блокировку при вызове синхронной функции в асинхронном коде в Python? (Python)
Уровень: senior · Роль: backend · Язык: Python · Категория: Технические вопросы
Компании: HeadHunter
Стек: Python
> Пример ответа
В асинхронном коде Python вызов синхронной блокирующей функции (например, time.sleep(), requests.get()) останавливает весь event loop, пока она выполняется. Основные способы обойти это:
-
Использовать
asyncio.to_thread()(Python 3.9+): запускает синхронную функцию в отдельном потоке, не блокируя event loop.PYTHONimport asyncioimport timeasync def main():result = await asyncio.to_thread(time.sleep, 2)print("Готово") -
Использовать
loop.run_in_executor(): более гибкий вариант, позволяет задать пул потоков или процессов.PYTHONimport asynciofrom concurrent.futures import ThreadPoolExecutorasync def main():with ThreadPoolExecutor() as executor:result = await asyncio.get_event_loop().run_in_executor(executor, time.sleep, 2) -
Для CPU-интенсивных задач - использовать
ProcessPoolExecutorчерезrun_in_executor, чтобы избежать GIL. -
Альтернатива для I/O-bound задач - заменить синхронную библиотеку на асинхронную (например,
aiohttpвместоrequests,asyncio.sleepвместоtime.sleep).
Выбор зависит от контекста: to_thread() - самый простой для быстрых блокировок, run_in_executor - для тонкой настройки, а замена библиотек - наиболее эффективный подход.
> Похожие задачи по Python
Какова иерархия процессов, потоков и asyncio в Python?
Что происходит при вызове синхронной функции из асинхронной ручки в FastAPI?
Что является верхнеуровневым и низкоуровневым компонентом в системах на SOLID?
Что такое дедлоки?
> Похожие задачи по backend
Какова иерархия процессов, потоков и asyncio в Python?
Что происходит при вызове синхронной функции из асинхронной ручки в FastAPI?
Что является верхнеуровневым и низкоуровневым компонентом в системах на SOLID?
Что такое дедлоки?
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью