2017-08-17 62 views
1

在Python中使用多處理並且您正在導入模塊時,爲什麼模塊中的任何實例變量都會通過副本傳遞給子進程,而參數args()中傳遞的參數是通過引用傳遞的。使用多處理模塊時未看到對對象屬性所做的更改

這是否與線程安全有關?

foo.py

class User: 
    def __init__(self, name): 
     self.name = name 


foo_user = User('foo') 

main.py

import multiprocessing 

from foo import User, foo_user 

def worker(main_foo): 
    print(main_foo.name) #prints 'main user' 
    print(foo_user.name) #prints 'foo user', why doesn't it print 'override' 

if __name__ == '__main__': 

    main_foo = User('main user') 
    foo_user.name = 'override' 

    p = multiprocessing.Process(target=worker, args=(main_foo,)) 
    p.start() 
    p.join() 

編輯:我是個白癡,self.name = None應該已經self.name = name。我在代碼中進行了更正,忘記將其複製過來。

+0

請參閱編輯 – dangel

回答

3

實際上,它確實打印覆蓋。看看這個:

$ python main.py 
None 
override 

但是!這隻發生在* Nix上。我的猜測是你在Windows上運行。不同之處在於,在Windows中,解釋器的新副本會生成爲僅運行您的函數,並且您對foo_user.name所做的更改未作出,因爲在此新實例中,__name__不是__main__,所以代碼位是沒執行。這是爲了防止無限遞歸。

你會看到區別,如果你加入這行到你的函數:

def worker(main_foo): 
    print(__name__) 
    ... 

這在* nix打印__main__。但是,對於Windows,它不會是__main__

如果你希望它可以工作,你會想要移動那行代碼if __name__ == __main__塊。

相關問題