我有一个多处理程序,我无法使用全局变量。我有一个程序,这样开始: -
from multiprocessing import Process ,Pool
print ("Initializing")
someList = []
...
...
...
这意味着我有一些在我的main调用之前初始化的List变量。
稍后在代码中someList被设置为某个值,然后我创建4个进程来处理它
pool = Pool(4)
combinedResult = pool.map(processFn, someList)
pool.close()
pool.join()
在生成进程之前,someList设置为有效值。
然而,当这些过程产生时,我看到这个打印4次!!
Initializing
Initializing
Initializing
Initializing
正如在每个过程中都清楚的那样,程序顶部的初始化部分被调用。此外,someList设置为空。如果我的理解是正确的,那么每个进程应该是当前进程状态的副本,这实际上意味着,我应该有4个相同列表的副本。为什么全局变量再次重新初始化?事实上,为什么该部分甚至被运行?
有人可以向我解释一下吗?我提到了python docs,但无法确定根本原因。他们建议不要使用全局变量并且我知道它,但它仍然没有解释对初始化函数的调用。另外,我想使用多处理而不是多线程。我试图了解多处理在这里是如何工作的。
感谢您的时间。
答案 0 :(得分:2)
在Windows中,进程不像Linux / Unix那样 forked 。相反,它们是衍生的,这意味着为每个新的multiprocessing.Process
启动了一个新的Python解释器。这意味着所有全局变量都被重新初始化,如果你在某种程度上操纵它们,那么生成的进程就不会看到它。
问题的解决方案是将全局变量传递给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)
在此设置中,您将全局变量复制到每个新进程,然后可以访问它们,但是,一如既往,从那里开始的任何更新都不会传播到任何其他进程。为此,您需要适当的multiprocessing.Manager
。
作为一个额外的评论,从这里很明显,全局变量可能是危险的,因为很难理解它们将在不同的过程中采用什么值。
答案 1 :(得分:0)
我认为重点在于,您正在创建4个进程,这些进程正在执行您提供的代码。它们在同一个实例中工作,但执行相同的代码。
所以,也许你做多线程或使用一些if子句等来确定哪个进程应该执行哪个代码。