Перейти к содержимому

Как сделать паузу в Python: time.sleep() и asyncio.sleep()

Опубликовано03.09.2026
Обновлено04.09.2026
Просмотры9
Время чтения7 мин.
Оглавление статьи
Практический гид по паузам в Python: выбираем между блокирующим и асинхронным ожиданием, проверяем единицы времени и не подменяем задержкой таймаут или синхронизацию.
Как сделать паузу в Python: time.sleep() и asyncio.sleep()

Короткий ответ

Чтобы сделать паузу в обычном Python-коде, вызовите time.sleep(seconds). Функция приостанавливает текущий поток минимум на указанное число секунд. В асинхронном коде используйте await asyncio.sleep(seconds): она приостанавливает только текущую задачу и отдаёт управление циклу событий.

import time

print("Старт")
time.sleep(2)
print("Прошло не меньше двух секунд")

Главное правило выбора: time.sleep() - для синхронного сценария, asyncio.sleep() - внутри корутины. Вызов time.sleep() внутри async def блокирует поток цикла событий и мешает другим задачам выполняться.

Как работает time.sleep()

time.sleep(seconds) входит в стандартный модуль time и не требует установки пакетов. Аргумент задаётся в секундах и может быть целым или дробным числом. Например, 0.5 означает половину секунды, а 0.001 - одну миллисекунду как запрошенный интервал.

import time

for step in range(3):
    print(f"Шаг {step + 1}")
    time.sleep(0.5)

Документация Python 3.14 уточняет: фактическая остановка может оказаться длиннее запрошенной из-за планирования других процессов и потоков операционной системой. Поэтому sleep() подходит для задержки, но не для точного таймера реального времени.

Что именно блокируется: time.sleep() приостанавливает вызывающий поток, а не обязательно весь процесс. Другие потоки могут продолжать работу. Но если это главный поток GUI или поток с циклом asyncio, интерфейс или все корутины этого цикла перестанут отвечать до окончания паузы.

time.sleep() и asyncio.sleep(): в чём разница

Критерийtime.sleep()asyncio.sleep()
Где использоватьОбычная функция, синхронный скриптКорутина async def
Как вызватьtime.sleep(1)await asyncio.sleep(1)
Что приостанавливаетсяТекущий потокТекущая задача
Могут ли выполняться другие корутины того же циклаНет, если вызов сделан в потоке event loopДа
Возвращаемое значениеNoneПереданный result или None
Нужен ли event loopНетДа

asyncio.sleep() всегда приостанавливает текущую задачу и позволяет циклу событий запустить готовую к работе корутину. Даже await asyncio.sleep(0) отдаёт управление планировщику по оптимизированному пути. Это не «сон всего приложения», а момент кооперативного переключения.

Пример asyncio.sleep() с двумя задачами

import asyncio

async def worker(name: str, delay: float) -> None:
    print(f"{name}: старт")
    await asyncio.sleep(delay)
    print(f"{name}: готово")

async def main() -> None:
    await asyncio.gather(
        worker("A", 1.0),
        worker("B", 0.5),
    )

asyncio.run(main())

Обе корутины стартуют, затем задача B становится готовой раньше задачи A. Если заменить await asyncio.sleep(delay) на time.sleep(delay), каждый вызов заблокирует поток event loop, и полезная конкурентность исчезнет.

Начиная с Python 3.13, asyncio.sleep(float("nan")) вызывает ValueError. Значение задержки, полученное из настроек или внешних данных, стоит проверять: оно должно быть конечным неотрицательным числом с понятной верхней границей.

Как сделать паузу на миллисекунды

Оба варианта принимают секунды как float. Переводите миллисекунды в секунды делением на 1000:

import time

milliseconds = 250
time.sleep(milliseconds / 1000)

Это запрос на паузу около 250 миллисекунд, а не гарантия пробуждения с точностью до миллисекунды. Разрешение таймера зависит от операционной системы, а выполнение продолжится только когда планировщик снова даст потоку процессорное время. Для измерения прошедшего интервала используйте time.perf_counter() или time.monotonic(), а не календарные часы.

Периодический запуск без накопления дрейфа

Цикл вида «работа, затем sleep(1)» постепенно отстаёт: длительность самой работы добавляется к каждому периоду. Для стабильного интервала рассчитывайте следующий дедлайн по монотонным часам.

import time

period = 1.0
next_run = time.monotonic()

for _ in range(5):
    print("Выполняем задачу")

    next_run += period
    remaining = next_run - time.monotonic()
    time.sleep(max(0.0, remaining))

time.monotonic() не движется назад при ручной смене системного времени. Если работа длится дольше периода, remaining станет отрицательным и очередная пауза будет нулевой. Для производственного планировщика нужно отдельно решить, пропускать ли просроченные запуски, объединять их или выполнять подряд.

Отменяемое ожидание в потоке

Спящий поток нельзя штатно разбудить через сам time.sleep(). Если фоновая задача должна быстро завершаться по сигналу, удобнее ждать threading.Event. Метод wait(timeout) возвращает True, когда событие установлено, и False, когда истёк таймаут.

import threading

stop_event = threading.Event()

def worker() -> None:
    while not stop_event.wait(timeout=5.0):
        print("Пять секунд прошли, продолжаем")

# Из другого потока:
stop_event.set()

Так фоновый цикл завершится сразу после set(), а не будет ждать остаток фиксированной паузы. В асинхронном коде отмена устроена иначе: задача, ожидающая asyncio.sleep(), может быть отменена и получит asyncio.CancelledError в ближайшей точке отмены. Очистку ресурсов размещайте в finally.

Задержка между повторными запросами

Фиксированная пауза между сетевыми повторами может создать синхронный всплеск нагрузки. Обычно используют экспоненциальный backoff с ограничением и случайным разбросом. Но сначала нужно выполнить правила конкретного : учитывать Retry-After, лимиты, идемпотентность операции и максимальное число попыток.

import random
import time

def backoff(attempt: int, base: float = 0.5, cap: float = 30.0) -> None:
    upper = min(cap, base * 2 ** attempt)
    time.sleep(random.uniform(0.0, upper))

Этот фрагмент только рассчитывает паузу. Он не решает, можно ли повторять запрос, и не заменяет обработку HTTP-ответов. Не повторяйте автоматически оплату, создание заказа или другую неидемпотентную операцию без ключа идемпотентности и правил сервиса.

Когда sleep() использовать не стоит

  • Ожидание готовности файла или сервиса. Проверяйте состояние с таймаутом либо используйте событие, очередь или callback.

  • Таймаут сетевой операции. Передавайте таймаут клиентской библиотеке; иначе запрос может зависнуть внутри вызова раньше вашего sleep().

  • Пауза в интерфейсе. Используйте таймер GUI-фреймворка, чтобы не блокировать главный цикл событий.

  • Синхронизация потоков. Применяйте Event, Condition, Lock или очередь, а не угадывайте время выполнения.

  • Планирование на часы и дни. Нужен планировщик с хранением состояния, обработкой перезапуска и часовых поясов.

  • CPU-bound задача в asyncio. asyncio.sleep() не ускоряет вычисления; выносите блокирующую работу в подходящий поток или процесс.

Частые ошибки

  • Писать sleep(1) без import time или явного импорта метода.

  • Передавать миллисекунды как секунды и случайно ждать в тысячу раз дольше.

  • Забывать await перед asyncio.sleep(): создаётся объект корутины, но пауза не выполняется.

  • Вызывать time.sleep() внутри async def и блокировать event loop.

  • Считать паузу точным будильником и игнорировать задержку планировщика.

  • Использовать time.time() для интервалов, хотя системные часы могут быть переведены.

  • Останавливать интерфейс sleep() в главном потоке.

  • Добавлять задержку вместо явной синхронизации или настоящего таймаута операции.

Как выбрать способ ожидания

ЗадачаИнструмент
Простая пауза в синхронном скриптеtime.sleep()
Неблокирующая пауза в корутинеawait asyncio.sleep()
Отменяемое ожидание фонового потокаthreading.Event.wait()
Измерение длительностиtime.perf_counter()
Расчёт дедлайна и периодаtime.monotonic()
Таймаут асинхронной операцииasyncio.timeout() или таймаут библиотеки
Отложенное действие в GUIТаймер конкретного GUI-фреймворка

Чек-лист перед добавлением паузы

  • Код синхронный или асинхронный?

  • Можно ли ждать событие вместо фиксированного времени?

  • Допустимо ли блокировать текущий поток?

  • Нужна ли возможность немедленной отмены?

  • Значение переведено в секунды и проверено на границы?

  • Используется монотонный таймер для интервалов?

  • У сетевой операции есть собственный таймаут?

  • Повтор запроса разрешён и не создаст дубль операции?

Вывод

time.sleep() - простой способ приостановить текущий поток в синхронном скрипте. asyncio.sleep() решает другую задачу: временно приостанавливает корутину и позволяет event loop выполнять другие задачи. Для отменяемого ожидания потока выбирайте Event.wait(), для интервалов - монотонные часы, а для сетевых и GUI-сценариев - таймауты и таймеры соответствующей библиотеки. Больше базовых конструкций собрано в практическом путеводителе по Python.

Официальные источники

Часто задаваемые вопросы

Как сделать паузу в Python?

В синхронном коде импортируйте модуль time и вызовите time.sleep(seconds). Функция приостановит текущий поток минимум на указанное число секунд.

Как сделать задержку на миллисекунды в Python?

Разделите миллисекунды на 1000: time.sleep(milliseconds / 1000). Это запрошенная минимальная пауза, а не гарантия точного пробуждения из-за работы системного планировщика.

Чем asyncio.sleep() отличается от time.sleep()?

time.sleep() блокирует текущий поток. await asyncio.sleep() приостанавливает только текущую асинхронную задачу и позволяет циклу событий выполнять другие готовые задачи.

Можно ли использовать time.sleep() внутри async def?

Технически вызов возможен, но он заблокирует поток event loop и остановит другие корутины этого цикла. В асинхронной функции обычно нужен await asyncio.sleep().

Почему asyncio.sleep() не работает без await?

asyncio.sleep() возвращает объект корутины. Без await, создания задачи или другого запуска корутина не выполняется, поэтому фактической паузы не происходит.

time.sleep() останавливает весь Python-процесс?

Она приостанавливает вызывающий поток. Другие потоки процесса могут продолжать работу, но пауза в главном потоке GUI или event loop блокирует обслуживаемые им задачи.

Как прервать sleep в потоке?

У time.sleep() нет штатного сигнала пробуждения. Для отменяемого ожидания используйте threading.Event.wait(timeout) и вызовите set() из другого потока.

Подходит ли sleep для точного таймера?

Нет. Пауза может длиться дольше запрошенной. Для измерения используйте time.perf_counter(), для дедлайнов time.monotonic(), а для точного планирования специализированный механизм.

Редакционная проверкаРедакция ИзмерьВебМатериал сверен редакцией: проверяем факты, актуальность условий и пользу для читателя.

Комментарии 0

Обсудите материал, задайте вопрос или дополните его своим опытом.

Присоединитесь к обсуждению

Комментарии доступны зарегистрированным пользователям. Почту нужно подтвердить один раз.

Пока нет комментариев

Начните обсуждение: задайте вопрос автору или поделитесь практическим опытом.