Многопроцессорность
Многопроцессорность — это подход к параллельному выполнению задач, при котором несколько процессов выполняются одновременно. В отличие от многопоточности, процессы не разделяют память, что делает многопроцессорность эффективной для задач, связанных с вычислениями (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 задач.