Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Когда использовать процессы (Process) в Python
Процессы используются для параллельного выполнения CPU-bound операций, когда нужна настоящая параллельность, а не просто переключение контекста. Каждый процесс имеет собственный интерпретатор Python и GIL.
Основные сценарии
1. CPU-bound вычисления
Это главная причина использования процессов:
from multiprocessing import Process, cpu_count
import time
def cpu_heavy_task(n):
"""Вычисления, которые требуют CPU"""
total = 0
for i in range(100_000_000):
total += i ** 2
return total
# Способ 1: ПОТОКИ (BAD — не работает параллельно)
import threading
import time
start = time.time()
threads = []
for i in range(4):
t = threading.Thread(target=cpu_heavy_task, args=(i,))
threads.append(t)
t.start()
for t in threads:
t.join()
thread_time = time.time() - start
print(f"Threading: {thread_time:.2f}s") # ~8s (последовательно)
# Способ 2: ПРОЦЕССЫ (GOOD — работает параллельно)
from concurrent.futures import ProcessPoolExecutor
start = time.time()
with ProcessPoolExecutor(max_workers=4) as executor:
results = list(executor.map(cpu_heavy_task, range(4)))
process_time = time.time() - start
print(f"Multiprocessing: {process_time:.2f}s") # ~2s (параллельно)
2. Data processing с большими объёмами
from multiprocessing import Pool
import numpy as np
def process_chunk(data_chunk):
"""Обработка одного куска данных"""
return np.mean(data_chunk)
# Генерируем большие данные
data = np.random.rand(1_000_000)
chunks = np.array_split(data, 8) # 8 кусков
# Распределяем обработку между процессами
with Pool(processes=4) as pool:
results = pool.map(process_chunk, chunks)
print(f"Average: {np.mean(results)}")
3. Machine Learning тренировка
from multiprocessing import Pool
from sklearn.ensemble import RandomForestClassifier
import numpy as np
def train_model(fold_data):
X_train, y_train = fold_data
model = RandomForestClassifier(n_jobs=-1) # Использует все ядра
model.fit(X_train, y_train)
return model
# K-fold cross validation на нескольких процессах
kfolds = 5
with Pool(processes=4) as pool:
models = pool.map(train_model, fold_data)
4. Обработка файлов
from multiprocessing import Pool
import os
import glob
def process_file(filepath):
"""Обработка одного файла"""
with open(filepath, r) as f:
content = f.read()
# Тяжёлая обработка
return len(content)
files = glob.glob("/data/*.txt")
with Pool(processes=8) as pool:
sizes = pool.map(process_file, files)
print(f"Total: {sum(sizes)} bytes")
Варианты использования процессов
Pool vs Process
# Pool — удобнее для множественных задач
from multiprocessing import Pool
with Pool(processes=4) as pool:
results = pool.map(func, data_list)
# Process — точнее контролируем
from multiprocessing import Process
proc = Process(target=func, args=(arg1, arg2))
proc.start()
proc.join()
print(proc.exitcode) # 0 if success
ProcessPoolExecutor — современный стиль
from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor(max_workers=4) as executor:
# Отправляем задачи
futures = [executor.submit(task, i) for i in range(100)]
# Получаем результаты по мере выполнения
for future in concurrent.futures.as_completed(futures):
result = future.result()
print(result)
Обмен данными между процессами
Queue — безопасный обмен
from multiprocessing import Process, Queue
def worker(queue):
queue.put("Hello from process")
queue = Queue()
proc = Process(target=worker, args=(queue,))
proc.start()
proc.join()
result = queue.get()
print(result) # Hello from process
Pipe — двусторонняя коммуникация
from multiprocessing import Process, Pipe
def worker(conn):
conn.send("Hello")
msg = conn.recv()
conn.close()
parent_conn, child_conn = Pipe()
proc = Process(target=worker, args=(child_conn,))
proc.start()
msg = parent_conn.recv()
print(msg) # Hello
proc.join()
Manager — shared объекты
from multiprocessing import Process, Manager
def worker(shared_dict, shared_list):
shared_dict["key"] = "value"
shared_list.append(42)
with Manager() as manager:
shared_dict = manager.dict()
shared_list = manager.list()
procs = [
Process(target=worker, args=(shared_dict, shared_list))
for _ in range(4)
]
for p in procs:
p.start()
for p in procs:
p.join()
print(shared_dict)
print(shared_list)
Когда НЕ использовать процессы
I/O-bound операции
# Плохо: процессы дорогие для I/O
import requests
from multiprocessing import Pool
def fetch_url(url):
return requests.get(url).text
# Хорошо: асинхронность
import asyncio
import aiohttp
async def fetch_url(url, session):
async with session.get(url) as resp:
return await resp.text()
async def main():
async with aiohttp.ClientSession() as session:
tasks = [fetch_url(url, session) for url in urls]
results = await asyncio.gather(*tasks)
asyncio.run(main())
Малые объёмы данных
# Не стоит: overhead создания процесса > выигрыш
with Pool(2) as pool:
result = pool.map(lambda x: x * 2, [1, 2, 3])
Сравнение: Threading vs Multiprocessing vs Async
| Параметр | Threading | Multiprocessing | Asyncio |
|---|---|---|---|
| CPU-bound | ❌ Плохо (GIL) | ✅ Отлично | ❌ Плохо |
| I/O-bound | ✅ Хорошо | ⚠️ Дорого | ✅ Лучше всего |
| Memory | Экономно | Тяжелый | Очень экономно |
| Простота | ✅ Просто | ❌ Сложно (обмен данных) | ⚠️ Async/await |
| Scalability | До ~100 потоков | До ~100 процессов | До 10k+ корутин |
Лучшие практики
# 1. Используй ProcessPoolExecutor для чистоты кода
from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor() as executor:
futures = executor.map(func, data)
# 2. Избегай обмена большими данными
# (процессы используют pickle для сериализации)
# 3. Кол-во процессов = кол-во ядер CPU
import os
workers = os.cpu_count()
# 4. Используй if __name__ == "__main__":
if __name__ == "__main__":
process = Process(target=worker)
process.start()
Резюме
Используй процессы для:
- CPU-bound вычисления (основное применение)
- Machine Learning тренировка
- Обработка больших объёмов данных
- Когда нужна настоящая параллельность (не GIL)
НЕ используй процессы для:
- I/O операций (используй asyncio)
- Малых объёмов данных (overhead велик)
- Частого обмена данными (используй потоки)