Python multiprocessing: параллельные процессы для быстрых вычислений
Многопоточность в Python открывает новые возможности для ускорения вычислений. Благодаря библиотеке multiprocessing можно запускать параллельные процессы на многоядерных процессорах. Это позволяет существенно сократить время обработки данных для задач машинного обучения, научных расчетов и веб-приложений. Давайте разберемся, как использовать преимущества многопроцессности в Python 3.
Основы многопроцессности в Python
Модуль multiprocessing в Python предназначен для организации параллельных вычислений с использованием нескольких процессов. В отличие от многопоточности, где используются легковесные потоки в рамках одного процесса, многопроцессность позволяет запускать полноценные процессы на разных ядрах процессора.
Многопоточность хороша для неблокирующих операций ввода-вывода, а многопроцессность - для CPU-интенсивных задач, требующих параллельных вычислений.
Основным преимуществом многопроцессности в Python является возможность распараллелить вычислительно тяжелые задачи между ядрами процессора. Это позволяет добиться линейного прироста производительности при увеличении количества ядер.
Например, обучение нейронной сети или научные вычисления могут выполняться в несколько раз быстрее за счет распределения нагрузки между процессами. Каждый процесс работает независимо в своем адресном пространстве.
Потоки vs процессы: сходства и различия
Потоки и процессы похожи тем, что позволяют выполнять код параллельно. Но есть несколько ключевых отличий:
- Потоки легковесны и разделяют общую память в рамках одного процесса.
- Процессы "тяжелее" и полностью изолированы друг от друга.
- Переключение между потоками проще, чем между процессами.
- Потоки эффективнее для неблокирующих операций ввода-вывода.
- Процессы лучше подходят для ресурсоемких параллельных вычислений.
В целом, выбор между потоками и процессами зависит от конкретной задачи и типа параллелизма, который требуется использовать.
Механизмы многопроцессности на разных ОС
Реализация многопроцессности в Python учитывает особенности разных операционных систем. На Unix-подобных системах (Linux, macOS) используется системный вызов fork(), который порождает дочерний процесс. В Windows применяется создание процессов через механизмы Win32 API.
Библиотека multiprocessing абстрагирует эти различия, поэтому код на Python работает одинаково на всех платформах. Но при необходимости можно управлять низкоуровневыми деталями запуска процессов через параметры start_method.
Класс Process для создания процессов
Для запуска процессов в модуле multiprocessing используется класс Process. Он позволяет создавать и управлять процессами из кода Python.
Создание объекта Process
Чтобы создать процесс, нужно передать вызываемый объект в конструктор класса Process:
from multiprocessing import Process def print_func(name): print("Hello", name) p = Process(target=print_func, args=('Bob',))
Здесь в аргументе target указана функция print_func, которая будет выполняться в дочернем процессе. Аргументы этой функции передаются в args как кортеж.
Настройка параметров процесса
При создании объекта Process можно настроить такие параметры, как имя процесса, группа и другие:
p = Process(name='printer', target=print_func, args=('Bob',)) p.daemon = True
Здесь задано имя 'printer' и установлен флаг daemon, который означает, что этот процесс не будет блокировать выход из основной программы.
Запуск процесса с помощью start()
"python multiprocessing" - использовано 2 раза
Чтобы реально запустить процесс после создания объекта, нужно вызвать метод start():
p.start()
Это создаст отдельный процесс и выполнит целевую функцию print_func в нем. Вызов p.start() асинхронный, управление сразу передается дальше.
Приостановка выполнения с join()
Чтобы дождаться завершения процесса, используется метод join():
p.join()
Это блокирует вызывающий процесс до тех пор, пока процесс p не завершится. Так можно синхронизировать выполнение.
Метод join() можно вызывать многократно, чтобы "подождать" завершения процесса в разных местах программы.