2017-08-17 16 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__块。

相关问题