python определяет разницу переменных до / после основного блока - PullRequest
0 голосов
/ 19 апреля 2020

Какая разница в python при определении переменной до или после основного блока? См. Переменную «блокировка» в следующих примерах кода.

Следующий код работает:

import multiprocessing
from multiprocessing import Lock

lock=Lock()

def single_process(num):
    lock.acquire()
    print(num)    
    lock.release()

if __name__ == "__main__":
    p1 = multiprocessing.Process(target=single_process, args=(123,)) 
    p2 = multiprocessing.Process(target=single_process, args=(456,)) 

    p1.start() 
    p2.start()

    p1.join()    
    p2.join()

, но следующий код не работает, говоря, что блокировка не определена:

import multiprocessing
from multiprocessing import Lock

def single_process(num):
    lock.acquire()
    print(num)    
    lock.release()

if __name__ == "__main__":

    lock=Lock()

    p1 = multiprocessing.Process(target=single_process, args=(123,)) 
    p2 = multiprocessing.Process(target=single_process, args=(456,)) 

    p1.start() 
    p2.start()

    p1.join()    
    p2.join()

1 Ответ

1 голос
/ 19 апреля 2020

Вы должны передать блокировку дочерним процессам через аргументы.


Объяснение:

Я думаю, что вы запускаете это на Windows , В любом случае не следует ожидать, что все объявленные вами переменные или значения, заданные вами в родительском процессе, будут автоматически доступны в дочерних процессах. См. this для синхронизации (блокировки) и this для различных способов обмена данными с дочерними процессами.

Тем не менее, оба опубликованных фрагмента кода выполняются для меня в моей системе (Linux). Разница в Linux заключается в том, что системный вызов fork () используется для запуска новых процессов. Форк делает копию вызывающего процесса. Таким образом, он наследует состояние основного процесса.

Вкл. Windows, системный вызов fork () отсутствует. Поэтому, когда дочерний процесс создается, модуль перезагружается в дочерних процессах без __name__, установленного на __main__ (в противном случае это приведет к fork bomb в вашем коде). Таким образом, в вашем первом фрагменте будет установлена ​​переменная lock в дочернем процессе, потому что она не находится внутри if __name__ == "__main__". Но в вашем втором фрагменте переменная блокировки не будет установлена, потому что она находится внутри блока if __name__ == "__main__".

...