Ответ
Использование 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() в асинхронном коде для сохранения его неблокирующей природы.
Ответ 18+ 🔞
А, слушай, смотри, вот это вообще классика, блядь! Как люди наступают на одни и те же грабли, ёпта!
Так, значит, смотри, есть у тебя эта самая асинхронность, корутины, event loop — вся эта магия, чтобы всё летало. И тут ты такой: «О, надо подождать секундочку», и пишешь time.sleep(2).
И всё, пиздец, блядь! Всё нахуй встало!
Представь: event loop — это такой охуенный диспетчер, который быстро-быстро переключается между задачами. Одна задача говорит: «Я подожду», диспетчер сразу бежит к другой. Всё шикарно.
А time.sleep() — это как если бы диспетчер, вместо того чтобы переключиться, взял и сам уснул нахуй. На два часа. И все остальные задачи стоят, блядь, в очереди и тупо ссут. Весь смысл асинхронности накрылся медным тазом.
Вот смотри на примере, тут всё ясно как божий день:
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())
Запустишь — и сразу увидишь разницу, как небо и земля. В первом случае another_task будет ждать, пока этот мудак с time.sleep проспится. А во втором — всё работает как часы, одна задача спит, другая работает, event loop доволен.
Короче, запомни раз и навсегда, как «Отче наш»: в асинхронном коде спим только через await asyncio.sleep(). Всё остальное — это ебать тебя в сраку, чувак, и убивать всю производительность. В рот меня чих-пых!