Ответ
Для CPU-bound задач (интенсивных вычислений, таких как обработка данных, математические расчеты) в Python наиболее эффективным подходом является многопроцессорность (multiprocessing).
Почему multiprocessing?
Основная причина — Global Interpreter Lock (GIL). GIL — это мьютекс, который защищает доступ к объектам Python, предотвращая одновременное выполнение байт-кода Python несколькими потоками в рамках одного процесса. Из-за этого многопоточность (threading) не дает прироста производительности для CPU-bound задач, так как потоки выполняются поочередно на одном ядре CPU.
Модуль multiprocessing обходит GIL, создавая отдельные процессы. Каждый процесс имеет свой собственный интерпретатор Python и пространство памяти, что позволяет им выполняться параллельно на разных ядрах процессора.
Пример с multiprocessing.Pool:
import time
from multiprocessing import Pool
def cpu_intensive_task(x):
# Имитация сложной вычислительной задачи
result = 0
for i in range(10**7):
result += i
return x * x
if __name__ == '__main__':
# Используем пул из 4 процессов
with Pool(4) as p:
result = p.map(cpu_intensive_task, range(10))
print(f"Результат: {result}")
Сравнение с другими подходами:
threading(многопоточность): Идеально подходит для I/O-bound задач (ожидание ответа от сети, чтение с диска), так как GIL освобождается во время ожидания, позволяя другому потоку выполняться.asyncio(асинхронность): Также предназначена для I/O-bound задач. Позволяет эффективно управлять тысячами одновременных соединений в одном потоке с помощью событийного цикла.
Вывод: Для распараллеливания вычислений на несколько ядер CPU в Python используйте multiprocessing или высокоуровневую обертку concurrent.futures.ProcessPoolExecutor.