Выбор ответа Middle asyncio обновлено

Как вызвать синхронную библиотеку из async-кода

Вопрос

Нужно вызвать синхронную функцию pdf_render(data) (блокирует на 2 секунды, отпускает GIL на I/O) из корутины, не останавливая цикл. Что использовать?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: await asyncio.tothread(pdfrender, data). asyncio.tothread (3.9+) выполняет функцию в пуле потоков и возвращает awaitable, цикл тем временем обслуживает другие задачи. await от обычной функции даст TypeError, ведь она возвращает не awaitable. asyncio.run нельзя вызывать из…

Варианты ответа

  1. await pdf_render(data), раз функция отпускает GIL
  2. asyncio.run(pdf_render(data))
  3. await asyncio.to_thread(pdf_render, data)правильный ответ
  4. Обернуть вызов в async def без изменений

Разбор

asyncio.to_thread (3.9+) выполняет функцию в пуле потоков и возвращает awaitable, цикл тем временем обслуживает другие задачи. await от обычной функции даст TypeError, ведь она возвращает не awaitable. asyncio.run нельзя вызывать из работающего цикла. Обёртка в async def ничего не меняет: код внутри всё равно блокирующий.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.