Процессом обычно называют запущенную программу. Для запуска операционная система выделяет определенную область памяти. Обычно она изолирована, поэтому процессы не могут влиять на работу друг друга, изменяя области памяти, которые им не принадлежат.
В python процессы применяют для распараллеливания тяжелых вычислений: вычисление хэшей, работы с матрицами, обработки изображений и иных подобных операций. Создавать процессы просто: достаточно создать объект класса Process и передать в него callable-объект, который должен запуститься в отдельном процессе.
Рассмотрим базовый пример:
1import time
2import os
3
4from multiprocessing import Process, current_process
5
6
7def foo(text: str) -> None:
8 time.sleep(3)
9
10 print('[foo] process name:', current_process().name)
11 print('[foo] process pid:', current_process().pid)
12 print('msg:', text)
13
14
15if __name__ == '__main__':
16 print('Main process pid:', os.getpid())
17
18 p = Process(target=foo, args=('Hello world', ), name='foo-process')
19 process_pid = p.pid
20 process_is_alive = p.is_alive()
21 print(f'Process with pid: {process_pid} is alive: {process_is_alive}')
22
23 print('Process started')
24 p.start()
25 process_pid = p.pid
26 process_is_alive = p.is_alive()
27 print(f'Process with pid: {process_pid} is alive: {process_is_alive}')
28
29 print('Waiting for the process ends...')
30 p.join()
31 process_pid = p.pid
32 process_is_alive = p.is_alive()
33 print(f'Process with pid: {process_pid} is alive: {process_is_alive}')
34
35 print('End program')
Вывод к консоль:
1Main process pid: 24569
2Process with pid: None is alive: False
3Process started
4Process with pid: 24570 is alive: True
5Waiting for the process ends...
6[foo] process name: foo-process
7[foo] process pid: 24570
8msg: Hello world
9Process with pid: 24570 is alive: False
10End program
Также, пока выполняется скрипт, во втором окне терминала выполните команду ps aux | grep <pid_number> для каждого полученного pid. В результате будет примерно следующее:
1~> ps aux | grep 24569
2darksto+ 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
3darksto+ 24578 0.0 0.0 17868 2280 pts/0 S+ 14:58 0:00 grep --color=auto 24569
4
5~> ps aux | grep 24570
6darksto+ 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
7darksto+ 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, который работает только с примитивными типами – числами, строками, словарями, функциями и т.п. Детальнее о взаимодействии между процессами можно прочитать в нашей статье.
Рассмотрим еще раз основные достоинста и недостатки процессов в python.
Достоинства
Недостатки