使用多处理模块时对对象属性所做的更改

时间:2017-08-17 02:52:31

标签: python python-multiprocessing

在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。我在代码中进行了更正,忘记将其复制回来。

1 个答案:

答案 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}}块,如果您希望它能够正常工作。

相关问题