python中的多进程是否重新初始化全局变量?

Nit*_*wal 2 python multithreading fork global-variables multiprocessing

我有一个无法处理全局变量的多处理程序。我有一个程序是这样开始的:-

from multiprocessing import Process ,Pool
print ("Initializing")
someList = []
...
...
... 
Run Code Online (Sandbox Code Playgroud)

这意味着我有 someList 变量,它们在调用 main 之前被初始化。

稍后在代码中将 someList 设置为某个值,然后我创建了 4 个进程来处理它

pool = Pool(4)
combinedResult = pool.map(processFn, someList)
pool.close()
pool.join()
Run Code Online (Sandbox Code Playgroud)

在产生进程之前, someList 被设置为一个有效值。

但是,当进程产生时,我看到这个打印 4 次!! Initializing Initializing Initializing Initializing

很明显,在每个进程中,程序顶部的初始化部分都会被调用。此外, someList 被设置为空。如果我的理解是正确的,每个进程都应该是当前进程状态的副本,这基本上意味着,我应该有 4 个相同列表的副本。为什么全局变量再次被重新初始化?事实上,为什么要运行该部分?

有人可以向我解释一下吗?我参考了 python 文档,但无法确定根本原因。他们确实建议不要使用全局变量,我知道这一点,但它仍然没有解释对初始化函数的调用。另外,我想使用多处理而不是多线程。我试图了解多处理在这里是如何工作的。

谢谢你的时间。

Joh*_*anL 9

在 Windows 中,进程不像在 Linux/Unix中那样分叉。相反,它们是生成的,这意味着为每个新的multiprocessing.Process. 这意味着所有全局变量都被重新初始化,如果您在此过程中以某种方式操纵了它们,则生成的进程将看不到这些。

该问题的解决方案是将全局变量传递给Pool initilaizer,然后从那里使其global也在生成的过程中:

from multiprocessing import Pool

def init_pool(the_list):
    global some_list
    some_list = the_list

def access_some_list(index):
    return some_list[index]

if __name__ == "__main__":
    some_list = [24, 12, 6, 3]
    indexes = [3, 2, 1, 0]
    pool = Pool(initializer=init_pool, initargs=(some_list,))
    result = pool.map(access_some_list, indexes)
    print(result)
Run Code Online (Sandbox Code Playgroud)

在此设置中,您将全局变量复制到每个新进程,然后它们就可以访问了,但是,与往常一样,从那里完成的任何更新都不会传播到任何其他进程。为此,您将需要类似适当的multiprocessing.Manager.

作为额外的评论,从这里很明显全局变量可能是危险的,因为很难理解它们在不同的过程中将采用什么值。