Sobes.tech
Назад к вопросам
Junior — Middle
71

Можно ли создавать новые потоки внутри асинхронных функций в Python?

Компании, где спрашивали
Магнит Тех

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

Да, внутри async def можно создавать и запускать потоки, но это не является типичным способом работы с asyncio. Асинхронная функция сама по себе не делает код параллельным для CPU-bound задач. Обычно потоки внутри async используют только для блокирующих операций, которые нужно вынести из event loop.

Определение:

Асинхронная функция в Python выполняется в event loop и должна по возможности оставаться неблокирующей. Если внутри нее создать новый поток, этот поток будет работать независимо от event loop, но код в потоке уже не является частью асинхронного исполнения. Поэтому важно понимать, что async и потоки решают разные задачи: asyncio — для конкурентного I/O, потоки — для изоляции блокирующих вызовов или интеграции с синхронным кодом.

Пример использования:

import asyncio
import threading

def blocking_work():
    print("Работа в отдельном потоке")

async def main():
    thread = threading.Thread(target=blocking_work)
    thread.start()
    await asyncio.sleep(1)
    thread.join()

asyncio.run(main())

Пояснение кода:

Код не требует специального async-API для создания потока: используется обычный threading.Thread.
Шаги такие: сначала создается поток с обычной синхронной функцией blocking_work, затем он запускается через start(), после чего асинхронная функция продолжает выполняться и может делать await-операции. В конце вызывается join(), чтобы дождаться завершения потока.

Ключевые моменты:

  • Создавать потоки внутри async def можно, но это обычные потоки, не “асинхронные потоки”.
  • asyncio не ускоряет CPU-bound код, а потоки внутри async не решают эту задачу автоматически.
  • Для блокирующего I/O лучше выносить работу в отдельный поток или использовать asyncio.to_thread, если доступно.
  • Нельзя блокировать event loop долгими синхронными операциями, иначе пострадает вся асинхронная программа.
  • Если внутри потока нужен доступ к asyncio, нужно отдельно продумывать взаимодействие с event loop, а не вызывать async-код напрямую.