Вопрос проверяет понимание различий между двумя подходами к параллельным вычислениям в Python и умение выбирать подходящий инструмент.
Оба инструмента в Python предназначены для параллельного выполнения задач в нескольких процессах, обходя ограничения GIL. Однако они имеют разные подходы к управлению задачами и обработке результатов.
Это классический способ создания пула процессов. Он предоставляет методы, такие как map(), apply(), starmap(), которые блокируют выполнение до получения всех результатов. Pool требует явного управления жизненным циклом (закрытие, ожидание завершения).
from multiprocessing import Pool
def square(x):
return x * x
with Pool(4) as pool:
results = pool.map(square, [1, 2, 3, 4])
print(results) # [1, 4, 9, 16]Это более современный интерфейс, вдохновленный Java. Он возвращает объекты Future, которые позволяют асинхронно получать результаты, добавлять колбэки и обрабатывать исключения. Executor поддерживает контекстный менеджер и легко интегрируется с asyncio через loop.run_in_executor().
from concurrent.futures import ProcessPoolExecutor
def square(x):
return x * x
with ProcessPoolExecutor(max_workers=4) as executor:
futures = [executor.submit(square, i) for i in [1, 2, 3, 4]]
results = [f.result() for f in futures]
print(results) # [1, 4, 9, 16]map, apply, starmap; Executor — submit и map.Для простых задач, где нужно применить функцию к списку данных, подойдет multiprocessing.Pool. Если требуется асинхронная обработка, управление исключениями или интеграция с asyncio, выбирайте concurrent.futures.ProcessPoolExecutor.