- Home »

Python time sleep: как приостановить выполнение кода в Python
Когда копаешься в серверных скриптах или настраиваешь автоматизацию, часто сталкиваешься с необходимостью приостановить выполнение кода на определенное время. Может быть, нужно дождаться завершения процесса, дать системе время на обработку данных, или просто сделать паузу между запросами к API, чтобы не получить бан за превышение лимитов. В Python для этого есть простой и эффективный инструмент — функция `time.sleep()`. Она может показаться тривиальной, но на практике открывает массу возможностей для создания стабильных и надежных скриптов.
Эта статья поможет разобраться с тем, как работает `time.sleep()`, где и как её правильно использовать, а также покажет продвинутые техники работы с задержками в Python. Если ты управляешь серверами, пишешь мониторинговые скрипты или создаешь автоматизацию для инфраструктуры, эти знания точно пригодятся.
Как работает time.sleep()
Функция `time.sleep()` — это встроенный метод модуля `time`, который приостанавливает выполнение текущего потока на указанное количество секунд. Принцип работы довольно простой: когда интерпретер Python встречает эту функцию, он передает управление операционной системе, которая “засыпает” поток на нужное время.
Основные характеристики:
- Принимает один аргумент — время в секундах (может быть float)
- Блокирует текущий поток выполнения
- Не потребляет CPU во время ожидания
- Точность зависит от операционной системы
import time
# Базовый пример
print("Начинаем работу...")
time.sleep(3) # Пауза 3 секунды
print("Продолжаем через 3 секунды")
# Можно использовать дробные значения
time.sleep(0.5) # Пауза 500 миллисекунд
print("Еще через полсекунды")
Быстрая настройка и базовые примеры
Для начала работы с `time.sleep()` никаких дополнительных установок не требуется — модуль `time` входит в стандартную библиотеку Python. Вот пошаговый подход для основных сценариев:
Шаг 1: Импорт и базовое использование
import time
# Простая задержка
time.sleep(5) # 5 секунд
# Для более читаемого кода можно использовать константы
DELAY_SECONDS = 10
time.sleep(DELAY_SECONDS)
Шаг 2: Интеграция в циклы для мониторинга
import time
import psutil
def monitor_cpu():
while True:
cpu_percent = psutil.cpu_percent(interval=1)
print(f"CPU usage: {cpu_percent}%")
if cpu_percent > 80:
print("⚠️ High CPU usage detected!")
time.sleep(5) # Проверяем каждые 5 секунд
# Запуск мониторинга
monitor_cpu()
Шаг 3: Работа с API и rate limiting
import time
import requests
def fetch_data_with_delay(urls):
results = []
for url in urls:
try:
response = requests.get(url)
results.append(response.json())
print(f"✅ Fetched: {url}")
except Exception as e:
print(f"❌ Error fetching {url}: {e}")
# Пауза между запросами
time.sleep(1) # 1 секунда между запросами
return results
# Пример использования
urls = [
"https://api.example.com/endpoint1",
"https://api.example.com/endpoint2",
"https://api.example.com/endpoint3"
]
data = fetch_data_with_delay(urls)
Практические кейсы и примеры использования
Позитивные сценарии
Сценарий | Описание | Пример кода |
---|---|---|
Мониторинг сервисов | Регулярная проверка статуса сервисов |
|
Batch processing | Обработка данных порциями с паузами |
|
Retry механизм | Повторные попытки с увеличивающейся задержкой |
|
Негативные сценарии (чего избегать)
- Блокировка GUI: Никогда не используй `time.sleep()` в главном потоке GUI-приложений
- Точное время: Не полагайся на `time.sleep()` для точного тайминга — есть погрешности
- Длительные задержки: Для задержек больше минуты лучше использовать планировщики задач
# ❌ Плохо — блокирует весь поток
def bad_example():
time.sleep(60) # 60 секунд блокировки
return "Finally done!"
# ✅ Лучше — с возможностью прерывания
import threading
import time
def better_example():
stop_event = threading.Event()
def worker():
for i in range(60):
if stop_event.is_set():
break
time.sleep(1)
thread = threading.Thread(target=worker)
thread.start()
return thread, stop_event
Альтернативы и похожие решения
Встроенные альтернативы
- threading.Event.wait(): Более гибкий механизм ожидания с возможностью прерывания
- asyncio.sleep(): Для асинхронного программирования
- signal.alarm(): Для Unix-систем, использует сигналы
# Пример с threading.Event
import threading
import time
def interruptible_sleep(seconds):
event = threading.Event()
event.wait(seconds)
return event
# Пример с asyncio
import asyncio
async def async_task():
print("Начинаем асинхронную задачу")
await asyncio.sleep(3) # Не блокирует другие задачи
print("Задача завершена")
# Запуск
asyncio.run(async_task())
Внешние библиотеки
- APScheduler: Для сложного планирования задач
- Celery: Для распределенной обработки задач
- schedule: Простая библиотека для планирования
# Пример с библиотекой schedule
# pip install schedule
import schedule
import time
def job():
print("Выполняем задачу...")
schedule.every(10).seconds.do(job)
schedule.every().hour.do(job)
while True:
schedule.run_pending()
time.sleep(1)
Продвинутые техники и интеграции
Экспоненциальные задержки (Exponential Backoff)
import time
import random
def exponential_backoff(max_retries=5, base_delay=1):
for attempt in range(max_retries):
try:
# Ваша операция здесь
result = potentially_failing_operation()
return result
except Exception as e:
if attempt == max_retries - 1:
raise e
# Экспоненциальная задержка с jitter
delay = base_delay * (2 ** attempt)
jitter = random.uniform(0, delay * 0.1)
total_delay = delay + jitter
print(f"Попытка {attempt + 1} неудачна. Ждем {total_delay:.2f} сек...")
time.sleep(total_delay)
Контекстный менеджер для задержек
import time
from contextlib import contextmanager
@contextmanager
def timed_delay(seconds):
start_time = time.time()
yield
elapsed = time.time() - start_time
remaining = seconds - elapsed
if remaining > 0:
time.sleep(remaining)
# Использование
with timed_delay(5):
# Код, который должен выполняться минимум 5 секунд
do_some_work()
# Если работа заняла меньше 5 секунд, добавится задержка
Интеграция с логированием
import time
import logging
# Настройка логирования
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def sleep_with_logging(seconds, message="Sleeping"):
logger.info(f"{message} for {seconds} seconds...")
time.sleep(seconds)
logger.info(f"{message} completed")
# Декоратор для автоматических задержек
def with_delay(seconds):
def decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
logger.info(f"Function {func.__name__} completed, sleeping {seconds}s")
time.sleep(seconds)
return result
return wrapper
return decorator
@with_delay(2)
def process_item(item):
return f"Processed {item}"
Статистика и сравнения
Производительность различных подходов
Метод | Точность | CPU использование | Прерываемость | Сложность |
---|---|---|---|---|
time.sleep() | ±10-15ms | Минимальное | Нет | Простая |
threading.Event.wait() | ±5-10ms | Минимальное | Да | Средняя |
asyncio.sleep() | ±1-5ms | Минимальное | Да | Высокая |
busy wait | Высокая | 100% CPU | Да | Простая |
Тестирование точности
import time
import statistics
def test_sleep_accuracy(duration, iterations=100):
delays = []
for _ in range(iterations):
start = time.perf_counter()
time.sleep(duration)
end = time.perf_counter()
actual_delay = end - start
delays.append(actual_delay)
avg_delay = statistics.mean(delays)
std_dev = statistics.stdev(delays)
print(f"Запрошенная задержка: {duration}s")
print(f"Средняя фактическая: {avg_delay:.4f}s")
print(f"Стандартное отклонение: {std_dev:.4f}s")
print(f"Ошибка: {(avg_delay - duration) * 1000:.2f}ms")
# Тестирование
test_sleep_accuracy(0.1) # 100ms
test_sleep_accuracy(1.0) # 1s
Интересные факты и нестандартные применения
Факты о time.sleep()
- Минимальная задержка зависит от системы: Windows ~15ms, Linux ~1ms
- Функция может “проспать” дольше запрошенного времени, но никогда меньше
- В многопоточных приложениях `time.sleep()` засыпает только текущий поток
- Под капотом использует системные вызовы `nanosleep()` (Linux) или `Sleep()` (Windows)
Креативные применения
# Прогресс-бар с анимацией
import time
import sys
def animated_progress(duration):
chars = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
end_time = time.time() + duration
while time.time() < end_time:
for char in chars:
sys.stdout.write(f"\r{char} Processing...")
sys.stdout.flush()
time.sleep(0.1)
print("\r✅ Done! ")
# Имитация печатания
def typewriter_effect(text, delay=0.05):
for char in text:
print(char, end='', flush=True)
time.sleep(delay)
print()
# Heartbeat мониторинг
def heartbeat_monitor(service_name, check_interval=30):
last_check = time.time()
while True:
current_time = time.time()
if current_time - last_check >= check_interval:
print(f"💓 {service_name} heartbeat - {time.strftime('%H:%M:%S')}")
last_check = current_time
time.sleep(1)
Автоматизация и интеграция в серверные скрипты
Скрипт для мониторинга сервера
#!/usr/bin/env python3
import time
import psutil
import requests
import logging
from datetime import datetime
# Настройка логирования
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('/var/log/server_monitor.log'),
logging.StreamHandler()
]
)
class ServerMonitor:
def __init__(self, check_interval=60):
self.check_interval = check_interval
self.running = True
def check_system_health(self):
# CPU проверка
cpu_percent = psutil.cpu_percent(interval=1)
# Память
memory = psutil.virtual_memory()
# Диск
disk = psutil.disk_usage('/')
# Сеть (проверка доступности)
network_ok = self.check_network()
return {
'cpu': cpu_percent,
'memory': memory.percent,
'disk': disk.percent,
'network': network_ok,
'timestamp': datetime.now()
}
def check_network(self):
try:
response = requests.get('https://httpbin.org/ip', timeout=5)
return response.status_code == 200
except:
return False
def send_alert(self, message):
logging.warning(f"🚨 ALERT: {message}")
# Здесь можно добавить отправку в Slack, Telegram и т.д.
def run(self):
logging.info("🚀 Server monitor started")
while self.running:
try:
health = self.check_system_health()
# Проверка пороговых значений
if health['cpu'] > 80:
self.send_alert(f"High CPU usage: {health['cpu']}%")
if health['memory'] > 90:
self.send_alert(f"High memory usage: {health['memory']}%")
if health['disk'] > 85:
self.send_alert(f"High disk usage: {health['disk']}%")
if not health['network']:
self.send_alert("Network connectivity issues")
logging.info(f"✅ Health check: CPU={health['cpu']}% "
f"MEM={health['memory']}% DISK={health['disk']}%")
except Exception as e:
logging.error(f"❌ Monitor error: {e}")
# Основная пауза между проверками
time.sleep(self.check_interval)
if __name__ == "__main__":
monitor = ServerMonitor(check_interval=30)
try:
monitor.run()
except KeyboardInterrupt:
logging.info("👋 Monitor stopped by user")
Backup скрипт с задержками
#!/usr/bin/env python3
import time
import subprocess
import os
from datetime import datetime
def backup_with_throttling():
"""Backup script с контролем нагрузки"""
backup_tasks = [
{'name': 'database', 'command': 'pg_dump mydb > /backup/db.sql'},
{'name': 'configs', 'command': 'tar -czf /backup/configs.tar.gz /etc/'},
{'name': 'logs', 'command': 'tar -czf /backup/logs.tar.gz /var/log/'},
{'name': 'uploads', 'command': 'rsync -av /var/uploads/ /backup/uploads/'}
]
for task in backup_tasks:
print(f"📦 Starting backup: {task['name']}")
start_time = time.time()
try:
result = subprocess.run(
task['command'],
shell=True,
capture_output=True,
text=True,
timeout=3600 # 1 hour timeout
)
duration = time.time() - start_time
if result.returncode == 0:
print(f"✅ {task['name']} completed in {duration:.2f}s")
else:
print(f"❌ {task['name']} failed: {result.stderr}")
except subprocess.TimeoutExpired:
print(f"⏰ {task['name']} timed out")
except Exception as e:
print(f"💥 {task['name']} error: {e}")
# Пауза между backup'ами для снижения нагрузки
if task != backup_tasks[-1]: # Не ждем после последней задачи
print("⏳ Cooling down...")
time.sleep(30) # 30 секунд между задачами
if __name__ == "__main__":
backup_with_throttling()
Развертывание на сервере
Для полноценного использования описанных скриптов в продакшене понадобится надежный сервер. Рекомендую обратить внимание на VPS решения для небольших проектов или выделенные серверы для высоконагруженных систем.
Заключение и рекомендации
Функция `time.sleep()` — это мощный инструмент, который при правильном использовании может значительно улучшить стабильность и производительность ваших скриптов. Вот основные рекомендации:
Когда использовать time.sleep():
- Мониторинговые скрипты с регулярными проверками
- Batch обработка данных с контролем нагрузки
- Retry механизмы с задержками
- Rate limiting для API запросов
- Простые периодические задачи
Когда выбрать альтернативы:
- asyncio.sleep(): для асинхронного кода
- threading.Event.wait(): когда нужна возможность прерывания
- APScheduler/Celery: для сложного планирования задач
- cron: для системных задач по расписанию
Лучшие практики:
- Используйте константы для задержек вместо магических чисел
- Логируйте задержки в важных местах
- Учитывайте погрешность времени при точных расчетах
- Предусматривайте возможность прерывания длительных операций
- Тестируйте поведение задержек в различных условиях
Помните, что `time.sleep()` — это простое решение для простых задач. Для сложных сценариев лучше использовать специализированные инструменты, но в арсенале каждого системного администратора и DevOps-инженера эта функция должна занимать почетное место.
Полезные ссылки:
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.