Ответ
Использование time.sleep()
в корутине полностью блокирует цикл событий (event loop) Python.
Почему это плохо?
time.sleep()
— это синхронная, блокирующая операция. Она останавливает выполнение всего потока, в котором запущен event loop, не давая ему возможности переключаться на другие задачи. В результате все остальные корутины "замирают" и ждут, пока time.sleep()
не завершится, что сводит на нет все преимущества асинхронности.
Правильное решение
В асинхронном коде следует использовать await asyncio.sleep()
. Эта функция не блокирует поток, а лишь приостанавливает выполнение текущей корутины и возвращает управление циклу событий. Event loop в это время может выполнять другие готовые к работе задачи.
Сравнительный пример:
import asyncio
import time
async def task_with_blocking_sleep():
print("Начало блокирующей задачи...")
# ПЛОХО: блокирует весь event loop на 2 секунды
time.sleep(2)
print("Блокирующая задача завершена.")
async def task_with_async_sleep():
print("Начало асинхронной задачи...")
# ХОРОШО: не блокирует, передает управление event loop
await asyncio.sleep(2)
print("Асинхронная задача завершена.")
async def another_task():
print("Другая задача выполняется!")
async def main():
# Запускаем блокирующую задачу и другую задачу параллельно
# 'another_task' не сможет выполниться, пока time.sleep() не закончится
print("--- Тест с time.sleep() ---")
await asyncio.gather(task_with_blocking_sleep(), another_task())
print("n--- Тест с asyncio.sleep() ---")
# 'another_task' выполнится немедленно, пока asyncio.sleep() ожидает
await asyncio.gather(task_with_async_sleep(), another_task())
asyncio.run(main())
Вывод: Всегда используйте await asyncio.sleep()
вместо time.sleep()
в асинхронном коде для сохранения его неблокирующей природы.