Многопроцессорность
Многопроцессорность — это подход к параллельному выполнению задач, при котором несколько процессов выполняются одновременно. В отличие от многопоточности, процессы не разделяют память, что делает многопроцессорность эффективной для задач, связанных с вычислениями (CPU-bound).
В Python для работы с процессами используется модуль multiprocessing
.
Основные понятия
- Процесс (Process): Это отдельный экземпляр программы с собственной памятью. Процессы не разделяют память, что позволяет избежать проблем с GIL (Global Interpreter Lock).
- Использование: Многопроцессорность подходит для CPU-bound задач, таких как вычисления, обработка данных или работа с большими массивами информации.
Создание процессов
Для создания процессов используется класс multiprocessing.Process
.
-
multiprocessing.Process
: Создаёт новый процесс. Аргументtarget
указывает функцию, которую нужно выполнить в процессе, аargs
— аргументы этой функции. -
start()
: Запускает процесс. -
join()
: Ожидает завершения процесса. Без этого основной процесс программы завершится раньше, чем рабочие процессы. -
time.sleep(2)
: Имитирует выполнение задачи, которая занимает 2 секунды.
Обмен данными между процессами
Для обмена данными между процессами используются специальные структуры, такие как multiprocessing.Queue
или multiprocessing.Pipe
.
Queue
:-
multiprocessing.Queue
: Потокобезопасная очередь для обмена данными между процессами. -
q.put(i)
: Добавляет элемент в очередь. -
q.get()
: Извлекает элемент из очереди. -
q.put(None)
: Сигнал для завершения работы потребителя.
Пул процессов
Для выполнения задач в пуле процессов используется multiprocessing.Pool
. Это удобно, когда нужно выполнить множество задач параллельно.
-
multiprocessing.Pool
: Создаёт пул процессов для параллельного выполнения задач. -
pool.map()
: Применяет функциюworker
к каждому элементу спискаrange(10)
. -
Результаты: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Совместное использование памяти
Для совместного использования памяти между процессами используются объекты multiprocessing.Value
и multiprocessing.Array
.
-
multiprocessing.Value
: Создаёт общую переменную, доступную для всех процессов. -
counter.value
: Доступ к значению переменной. -
Вывод:
Итоговое значение counter: 200000
Практические задачи
Задача 1: Многопроцессорный расчёт факториала
Напишите многопроцессорную программу для вычисления факториала чисел.
Решение:-
multiprocessing.Pool
: Создаёт пул процессов для параллельного вычисления факториалов. -
pool.map()
: Применяет функциюfactorial
к каждому числу в списке. -
Вывод:
Факториалы: [120, 3628800, 1307674368000, 2432902008176640000]
Задача 2: Многопроцессорный поиск простых чисел
Напишите многопроцессорную программу для поиска простых чисел в заданном диапазоне.
Решение:-
pool.starmap()
: Применяет функциюfind_primes
к каждому диапазону чисел. -
is_prime()
: Проверяет, является ли число простым. -
Вывод:
Простые числа: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293]
Рекомендации
- Используйте многопроцессорность для CPU-bound задач, таких как вычисления или обработка данных.
-
Для обмена данными между процессами используйте
multiprocessing.Queue
илиmultiprocessing.Pipe
. -
Для выполнения задач в пуле процессов используйте
multiprocessing.Pool
. -
Для совместного использования памяти используйте
multiprocessing.Value
иmultiprocessing.Array
.
Сравнение многопоточности и многопроцессорности
Характеристика | Многопоточность (Threading) | Многопроцессорность (Multiprocessing) |
---|---|---|
Память | Общая память | Раздельная память |
GIL | Есть (ограничивает параллелизм) | Нет (полный параллелизм) |
Использование | I/O-bound задачи | CPU-bound задачи |
Сложность | Проще (общая память) | Сложнее (раздельная память) |
Многопроцессорность в Python — это мощный инструмент для выполнения задач, связанных с вычислениями. Она позволяет эффективно использовать ресурсы процессора и избежать ограничений GIL. Используйте её для ускорения выполнения CPU-bound задач.