Что такое многопроцессность?
Это вариант реализации вычислений, когда для решения некоторой прикладной задачи запускается несколько независимых процессов. В системах, где под процессом понимается сущность, владеющая ресурсами (памятью, открытыми файлами, сетевыми подключениями), несколько процессов запускаются с целью повышения отказоустойчивости приложения а также с целью повышения безопасности.
Процессы позволяют выполнять задачи на разных ядрах компьютера. Это важно для задач, которые завязаны на CPU. Процессы в Python позволяют запустить выполнение нескольких задач в параллельном режиме. По сути, при старте процесса запускает еще одна копия интерпретатора Python, в котором выполняется указанная функция. Таким образом, если мы запустим пять процессов, то будет запущено пять отдельных интерпретаторов, в этом случае уже не будет проблем с GIL. Такой способ позволяет параллельно запускать задачи активно использующие CPU. Они будут распределяться между несколькими процессами (ядрами), что значительно увеличит производительность вычислений.
Что такое многопоточность?
Поток — это не что иное, как сегмент процесса. Потоки — исполняемые сущности, которые выполняют задачи, стоящие перед исполняемым приложением. Процесс завершается, когда все потоки заканчивают выполнение.
Потоки позволяют запустить выполнение нескольких задач в конкурентном режиме в рамках одного процесса интерпретатора. При этом, нужно помнить о GIL. Все потоки будут выполняться на одном CPU, даже если задачи могут выполняться параллельно. Поэтому есть такое правило, если ваши задачи в основном потребляют ресурсы процессора, то используйте процессы, если ввод-вывод, то потоки и другие инструменты асинхронного программирования, которые в Python обладают довольно мощным функционалом.
Потоки на Python не дают никаких преимуществ для задач, создающих интенсивную вычислительную нагрузку на процессор, именно из-за GIL
Роль ядер процессора
Каждый поток в процессе — это задача, которую должен выполнить процессор.
Большинство процессоров сегодня умеют выполнять одновременно две задачи на одном ядре, создавая дополнительное виртуальное ядро. Это называется одновременная многопоточность или многопоточность Hyper-Threading, если речь о процессоре от Intel. Эти процессоры называются многоядерными процессорами. Таким образом, двухъядерный процессор имеет 4 ядра: два физических и два виртуальных. Каждое ядро может одновременно выполнять только один поток.
Различие процессов от потоков
Каждый процесс выполняется в отдельном адресном пространстве: один процесс не может получить доступ к переменным и структурам данных другого. Если процесс хочет получить доступ к чужим ресурсам, необходимо использовать межпроцессное взаимодействие. Это могут быть конвейеры, файлы, каналы связи между компьютерами и многое другое.
Поток использует то же самое пространства стека, что и процесс, а множество потоков совместно используют данные своих состояний. Как правило, каждый поток может работать (читать и писать) с одной и той же областью памяти, в отличие от процессов, которые не могут просто так получить доступ к памяти другого процесса. У каждого потока есть собственные регистры и собственный стек, но другие потоки могут их использовать.
GIL в python
GIL — это аббревиатура от Global Interpreter Lock – глобальная блокировка интерпретатора. Он является элементом эталонной реализации языка Python, которая носит название CPython. Суть GIL заключается в том, что выполнять байт код может только один поток. Это нужно для того, чтобы упростить работу с памятью (на уровне интерпретатора) и сделать комфортной разработку модулей на языке C. Это приводит к некоторым особенностям, о которых необходимо помнить. Условно, все задачи можно разделить на две большие группы: в первую входят те, что преимущественно используют процессор для своего выполнения, например, математические, их ещё называют CPU-bound, во вторую – задачи работающие с вводом выводом (диск, сеть и т.п.), такие задачи называют IO-bound.
Модуль multiprocessing в python
Модуль multiprocessing изначально был добавлен в Python 2.6. Этот модуль позволяет создавать процессы таким же образом, как при создании потоков при помощи модуля threading.
Суть в том, что, в связи с тем, что теперь мы создаем процессы, появляется возможность обойти GIL (Global Interpreter Lock) и воспользоваться возможностью использования нескольких процессоров (или даже ядер) на компьютере.
Класс Pool
Класс Pool используется для создания пула рабочих процессов. Он включает в себя методы, которые позволяют вам разгружать задачи к рабочим процессам. Давайте посмотрим на простейший пример.
Заключение
Программа выполняется намного быстрее при многопроцессной обработке примерно при одновременном выполнении 4 подпроцессов.
Если ваш код использует много операций ввода-вывода или сети, многопоточность - ваш лучший выбор из-за низких накладных расходов.
Если ваш код привязан к процессору, вам следует использовать многопроцессную обработку (если ваша машина имеет несколько ядер)
Многопроцессорная обработка была полезна для задачи с интенсивным использованием процессора, потому что мы могли бы извлечь выгоду из использования нескольких ядер и избежать глобальной блокировки интерпретатора.
Список литературы
https://russianblogs.com/article/8119194607/
https://medium.com/nuances-of-programming/основы-многопоточности-e355dd5a64b9
https://pyneng.readthedocs.io/ru/latest/book/19_concurrent_connections/cpython_gil.html
https://devpractice.ru/python-lesson-24-concurrency-part-3/
https://qna.habr.com/q/342807
https://teletype.in/@python_academy/T5DXZot4I
https://medium.com/nuances-of-programming/потоковые-и-многопроцессорные-модули-на-python-1a86a6d8986f
https://tproger.ru/problems/what-is-the-difference-between-threads-and-processes/
Материалы на данной страницы взяты из открытых источников либо размещены пользователем в соответствии с договором-офертой сайта. Вы можете сообщить о нарушении.