Содержание
Процессом обычно называют запущенную программу. Для запуска операционная система выделяет определенную область памяти. Обычно она изолирована, поэтому процессы не могут влиять на работу друг друга, изменяя области памяти, которые им не принадлежат.
В python процессы применяют для распараллеливания тяжелых вычислений: вычисление хэшей, работы с матрицами, обработки изображений и иных подобных операций. Создавать процессы просто: достаточно создать объект класса Process и передать в него callable-объект, который должен запуститься в отдельном процессе.
В python процессы применяют для распараллеливания тяжелых вычислений: вычисление хэшей, работы с матрицами, обработки изображений и иных подобных операций. Создавать процессы просто: достаточно создать объект класса Process и передать в него callable-объект, который должен запуститься в отдельном процессе.
Рассмотрим пример
Рассмотрим базовый пример:
import time
import os
from multiprocessing import Process, current_process
def foo(text: str) -> None:
time.sleep(3)
print('[foo] process name:', current_process().name)
print('[foo] process pid:', current_process().pid)
print('msg:', text)
if __name__ == '__main__':
print('Main process pid:', os.getpid())
p = Process(target=foo, args=('Hello world', ), name='foo-process')
process_pid = p.pid
process_is_alive = p.is_alive()
print(f'Process with pid: {process_pid} is alive: {process_is_alive}')
print('Process started')
p.start()
process_pid = p.pid
process_is_alive = p.is_alive()
print(f'Process with pid: {process_pid} is alive: {process_is_alive}')
print('Waiting for the process ends...')
p.join()
process_pid = p.pid
process_is_alive = p.is_alive()
print(f'Process with pid: {process_pid} is alive: {process_is_alive}')
print('End program')
import os
from multiprocessing import Process, current_process
def foo(text: str) -> None:
time.sleep(3)
print('[foo] process name:', current_process().name)
print('[foo] process pid:', current_process().pid)
print('msg:', text)
if __name__ == '__main__':
print('Main process pid:', os.getpid())
p = Process(target=foo, args=('Hello world', ), name='foo-process')
process_pid = p.pid
process_is_alive = p.is_alive()
print(f'Process with pid: {process_pid} is alive: {process_is_alive}')
print('Process started')
p.start()
process_pid = p.pid
process_is_alive = p.is_alive()
print(f'Process with pid: {process_pid} is alive: {process_is_alive}')
print('Waiting for the process ends...')
p.join()
process_pid = p.pid
process_is_alive = p.is_alive()
print(f'Process with pid: {process_pid} is alive: {process_is_alive}')
print('End program')
Вывод к консоль:
Main process pid: 24569
Process with pid: None is alive: False
Process started
Process with pid: 24570 is alive: True
Waiting for the process ends...
[foo] process name: foo-process
[foo] process pid: 24570
msg: Hello world
Process with pid: 24570 is alive: False
End program
Process with pid: None is alive: False
Process started
Process with pid: 24570 is alive: True
Waiting for the process ends...
[foo] process name: foo-process
[foo] process pid: 24570
msg: Hello world
Process with pid: 24570 is alive: False
End program
Также, пока выполняется скрипт, во втором окне терминала выполните команду ps aux | grep <pid_number> для каждого полученного pid. В результате будет примерно следующее:
~> ps aux | grep 24569
darksto+ 24569 0.6 0.0 28316 11192 ? S 14:58 0:00 ~/PycharmProjects/edu/async-python-sprint-1/.venv/bin/python ~/.config/JetBrains/PyCharm2022.3/scratches/scratch.py
darksto+ 24578 0.0 0.0 17868 2280 pts/0 S+ 14:58 0:00 grep --color=auto 24569
~> ps aux | grep 24570
darksto+ 24570 0.0 0.0 28316 8968 ? S 14:58 0:00 ~/PycharmProjects/edu/async-python-sprint-1/.venv/bin/python ~/.config/JetBrains/PyCharm2022.3/scratches/scratch.py
darksto+ 24590 0.0 0.0 17868 2312 pts/0 S+ 14:58 0:00 grep --color=auto 24570
darksto+ 24569 0.6 0.0 28316 11192 ? S 14:58 0:00 ~/PycharmProjects/edu/async-python-sprint-1/.venv/bin/python ~/.config/JetBrains/PyCharm2022.3/scratches/scratch.py
darksto+ 24578 0.0 0.0 17868 2280 pts/0 S+ 14:58 0:00 grep --color=auto 24569
~> ps aux | grep 24570
darksto+ 24570 0.0 0.0 28316 8968 ? S 14:58 0:00 ~/PycharmProjects/edu/async-python-sprint-1/.venv/bin/python ~/.config/JetBrains/PyCharm2022.3/scratches/scratch.py
darksto+ 24590 0.0 0.0 17868 2312 pts/0 S+ 14:58 0:00 grep --color=auto 24570
Видим, что в один момент времени существуют два процесса, с соответсвующими pid.
Разберем пример кода по шагам. Вначале добавляем необходимые импорты и функцию foo. Внутри функции добавляем вывод названия и pid текущего процесса, в котором выполняется функция.
Начинаем основной блок программы. С помощью модуля os выводим pid основного процесса.
Создаем экземпляр класса Process, передав в него, через параметр target, callable объект (функцию foo), ее аргументы и название процесса. Метод is_alive() позволяет определить запущен процесс или нет. С помощью метода start() запускаем процесс, а добавление метода join() в основной код, позволяет дождаться завершения дочернего процесса.
Если необходимо выполнить прерывание работы процесса из основной части программы, не дожидаясь его выполнения можно использовать метод процесса terminate().
Для сериализации и десериализации объектов при взаимодействии с процессами используется модуль pickle, который работает только с примитивными типами – числами, строками, словарями, функциями и т.п. Детальнее о взаимодействии между процессами можно прочитать в нашей статье.
Разберем пример кода по шагам. Вначале добавляем необходимые импорты и функцию foo. Внутри функции добавляем вывод названия и pid текущего процесса, в котором выполняется функция.
Начинаем основной блок программы. С помощью модуля os выводим pid основного процесса.
Создаем экземпляр класса Process, передав в него, через параметр target, callable объект (функцию foo), ее аргументы и название процесса. Метод is_alive() позволяет определить запущен процесс или нет. С помощью метода start() запускаем процесс, а добавление метода join() в основной код, позволяет дождаться завершения дочернего процесса.
Если необходимо выполнить прерывание работы процесса из основной части программы, не дожидаясь его выполнения можно использовать метод процесса terminate().
Для сериализации и десериализации объектов при взаимодействии с процессами используется модуль pickle, который работает только с примитивными типами – числами, строками, словарями, функциями и т.п. Детальнее о взаимодействии между процессами можно прочитать в нашей статье.
Заключение
Рассмотрим еще раз основные достоинста и недостатки процессов в python.
Достоинства
Недостатки
Достоинства
- Возможность использовать все доступные ядра процессора
- GIL не накладывает своих ограничений
- У каждого процесса своя область памяти
- Есть возможность прервать процесс
- Подходит для тяжелых вычислений
Недостатки
- Более сложный интерфейс и больше накладные расходы
- Большое потребление памяти