Какие типы задач решаются с помощью модуля multiprocessing в Python?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Модуль multiprocessing в Python: типы решаемых задач
Модуль multiprocessing в Python предназначен для работы с настоящим параллелизмом на уровне операционной системы, обходя ограничения GIL (Global Interpreter Lock). Это позволяет использовать несколько ядер процессора и решать вычислительно интенсивные задачи.
Основные типы задач
1. Вычислительно интенсивные операции
Это основное применение multiprocessing. Когда нужно выполнить тяжёлые математические вычисления, обработку данных или научные расчёты:
from multiprocessing import Pool
import math
def compute_pi(n):
"""Вычисление числа Пи методом Монте-Карло"""
count = 0
for _ in range(n):
x = math.sqrt(math.random())
y = math.sqrt(math.random())
if x*x + y*y <= 1:
count += 1
return count
if __name__ == '__main__':
with Pool(4) as pool:
results = pool.map(compute_pi, [1000000] * 4)
total_pi = (sum(results) / 4000000) * 4
print(f"Приблизительное значение Pi: {total_pi}")
2. Параллельная обработка больших объёмов данных
Обработка файлов, логов, датасетов, когда данные можно разделить на части:
from multiprocessing import Process
import os
def process_chunk(filename, start, end, process_id):
"""Обработка части файла процессом"""
with open(filename, 'r') as f:
lines = f.readlines()[start:end]
processed = [line.upper() for line in lines]
print(f"Процесс {process_id}: обработано {len(processed)} строк")
if __name__ == '__main__':
num_processes = 4
chunk_size = 1000
processes = []
for i in range(num_processes):
p = Process(target=process_chunk,
args=('data.txt', i*chunk_size, (i+1)*chunk_size, i))
processes.append(p)
p.start()
for p in processes:
p.join()
3. Независимые фоновые задачи
Запуск процессов, которые не зависят друг от друга и могут выполняться параллельно:
from multiprocessing import Process
import time
def fetch_data(url, result_list):
"""Получение данных от API"""
time.sleep(2) # Имитация сетевого запроса
result_list.append(f"Data from {url}")
def save_to_db(data):
"""Сохранение в БД"""
time.sleep(1)
print(f"Saved: {data}")
if __name__ == '__main__':
processes = []
urls = ['http://api1.com', 'http://api2.com', 'http://api3.com']
for url in urls:
p = Process(target=fetch_data, args=(url, []))
p.start()
processes.append(p)
for p in processes:
p.join()
4. Долгоживущие рабочие процессы
Пулы процессов для обработки очереди задач или постоянной работы:
from multiprocessing import Pool, Queue
from queue import Empty
import time
def worker(task_queue, worker_id):
"""Рабочий процесс, обрабатывающий задачи из очереди"""
while True:
try:
task = task_queue.get(timeout=1)
if task is None: # Сигнал выхода
break
print(f"Worker {worker_id}: обработка {task}")
time.sleep(0.5)
except Empty:
pass
if __name__ == '__main__':
task_queue = Queue()
# Запуск рабочих процессов
workers = [Process(target=worker, args=(task_queue, i))
for i in range(4)]
for w in workers:
w.start()
# Добавление задач
for task_id in range(20):
task_queue.put(f"Task-{task_id}")
# Завершение
for _ in range(4):
task_queue.put(None)
for w in workers:
w.join()
5. Параллельный веб-скрейпинг и сетевые запросы
Оптимизация сетевых операций, ограниченных не CPU, а задержками сети:
from multiprocessing import Pool
import requests
import time
def fetch_url(url):
"""Загрузка содержимого страницы"""
try:
response = requests.get(url, timeout=5)
return url, len(response.content)
except Exception as e:
return url, f"Error: {e}"
if __name__ == '__main__':
urls = [
'https://example.com',
'https://python.org',
'https://github.com',
] * 10
start = time.time()
with Pool(4) as pool:
results = pool.map(fetch_url, urls)
print(f"Время: {time.time() - start:.2f}s")
for url, size in results:
print(f"{url}: {size} bytes")
Сравнение многопроцессности с другими подходами
| Задача | threading | multiprocessing | asyncio |
|---|---|---|---|
| CPU-bound | ✗ (GIL) | ✓ | ✗ (GIL) |
| IO-bound | ✓ | ✓ | ✓ (лучше) |
| Простота | ✓ | ✗ | ✓ |
| Overhead | Низкий | Высокий | Низкий |
Когда НЕ использовать multiprocessing
- Часто создаёте новые процессы — дорого по ресурсам
- Нужен частый обмен данными — медленнее threading
- Используете Windows — сложнее с инициализацией
- IO-bound операции с малыми задержками — лучше asyncio
Практический совет
Для IO-bound задач (API, БД, файлы) обычно выбирают asyncio как более эффективный вариант. multiprocessing оправдан когда действительно нужно параллельно использовать несколько ядер процессора для вычислений.