все Python 3multiprocessingпонятие
multiprocessing.Process
процессы
Отдельный процесс ОС со своим интерпретатором и своей памятью: target запускается в нём после start(), join() ждёт завершения. Обходит GIL для счётных задач.
Синтаксис
p = ctx.Process(target=func, args=(...), kwargs={}, name=None, daemon=None); p.start(); p.join(timeout=None)
Код запуска держите под if __name__ == '__main__': при spawn (Windows, macOS) и forkserver (Linux с 3.14) ребёнок заново импортирует главный модуль, и без этой защиты он сам начал бы плодить процессы — получите RuntimeError. target и args передаются через pickle, поэтому lambda и вложенные функции не годятся — только функции верхнего уровня модуля. Память не общая: изменённая в ребёнке глобальная переменная родителю не видна. Исключение в ребёнке до родителя не долетает — только трассировка в stderr и exitcode 1, проверяйте его после join().
Примеры
import multiprocessing as mp
counter = 0
def work(n):
global counter
counter += n
print('child counter', counter) # → child counter 5
if __name__ == '__main__':
ctx = mp.get_context('spawn')
p = ctx.Process(target=work, args=(5,))
p.start()
p.join()
print(p.exitcode, counter) # → 0 0 — у родителя своя копия переменной
import multiprocessing as mp
if __name__ == '__main__':
ctx = mp.get_context('spawn')
p = ctx.Process(target=int, args=('oops',)) # ValueError в ребёнке
p.start()
p.join()
print('parent still alive, exitcode', p.exitcode) # → parent still alive, exitcode 1
import multiprocessing as mp
if __name__ == '__main__':
ctx = mp.get_context('spawn')
p = ctx.Process(target=lambda: print('hi'))
try:
p.start()
except Exception as e:
print('lambda cannot be pickled:', type(e).__name__) # → lambda cannot be pickled: PicklingError
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности