Ответ
Да, Python-скрипт по умолчанию выполняется в одном главном потоке. Однако для задач автоматизации в DevOps часто требуется параллельное выполнение операций (например, одновременная проверка множества серверов или параллельная загрузка файлов).
1. Многопоточность (threading):
Потоки в Python подходят для задач, связанных с вводом-выводом (I/O-bound), где время тратится на ожидание сети, диска и т.д. Несмотря на Global Interpreter Lock (GIL), потоки могут работать параллельно в такие моменты ожидания.
Пример: параллельные HTTP-запросы к нескольким эндпоинтам для мониторинга:
import threading
import requests
from concurrent.futures import ThreadPoolExecutor
def check_url(url):
try:
resp = requests.get(url, timeout=5)
return f"{url}: {resp.status_code}"
except Exception as e:
return f"{url}: ERROR - {e}"
urls = ["http://api1.example.com/health", "http://api2.example.com/health"]
# Использование ThreadPoolExecutor - лучшая практика
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(check_url, urls))
for result in results:
print(result)
2. Мультипроцессинг (multiprocessing):
Для CPU-интенсивных задач (например, шифрование, сжатие данных) нужно использовать процессы, так как они обходят ограничение GIL, используя отдельные интерпретаторы Python.
Пример: параллельная обработка лог-файлов:
from multiprocessing import Pool
import gzip
def process_log_file(filename):
with gzip.open(filename, 'rt') as f:
return sum(1 for line in f if 'ERROR' in line)
file_list = ['app1.log.gz', 'app2.log.gz']
with Pool(processes=2) as pool:
error_counts = pool.map(process_log_file, file_list)
3. Асинхронное программирование (asyncio):
Идеально для высоконагруженных сетевых задач (например, свой мониторинг или оркестратор).
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in url_list]
results = await asyncio.gather(*tasks)
Выбор подхода зависит от задачи: threading для множества I/O-операций, multiprocessing для тяжелых вычислений, asyncio для максимальной эффективности в сетевых операциях.