在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 :(得分:3)
实际上,它 打印覆盖。看看这个:
$ python main.py
None
override
但是!这只发生在* Nix上。我的猜测是你在Windows上运行。不同之处在于,在Windows中,生成解释器的新副本以仅运行您的函数,并且未对foo_user.name
进行更改,因为在此新实例中,__name__
不是__main__
,因此不会执行一些代码。这样做是为了防止无限递归。
如果您将此行添加到您的函数中,您将看到不同之处:
def worker(main_foo):
print(__name__)
...
这会在* Nix上打印__main__
。但是,对于Windows,它不会是__main__
。
您希望移动该行<{1}}块,如果您希望它能够正常工作。