我有一个多处理程序,我无法使用全局变量。我有一个程序,它是这样开始的:-
from multiprocessing import Process ,Pool
print ("Initializing")
someList = []
...
...
...
这意味着我有一些List变量,这些变量在调用我的main之前被初始化。
稍后在代码中将someList设置为某个值,然后我创建4个进程来处理它
pool = Pool(4)
combinedResult = pool.map(processFn, someList)
pool.close()
pool.join()
在生成进程之前,someList 设置为有效值。
但是,当生成进程时,我看到此打印 4 次!
Initializing
Initializing
Initializing
Initializing
很明显,在每个进程中,程序顶部的初始化部分都会被调用。此外,someList 被设置为空。如果我的理解是正确的,每个进程都应该是当前进程状态的副本,这基本上意味着,我应该得到同一列表的 4 个副本。为什么再次重新初始化全局变量?事实上,为什么还要运行该部分?
有人可以向我解释一下吗?我参考了python文档,但无法确定根本原因。他们确实建议不要使用全局变量,我知道这一点,但它仍然没有解释对初始化函数的调用。另外,我想使用多处理而不是多线程。我试图了解多处理在这里的工作原理。
谢谢你的时间。
在Windows中,进程不像Linux/Unix那样分叉。相反,它们被生成,这意味着为每个新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
.
作为额外的评论,从这里可以清楚地看出全局变量可能是危险的,因为很难理解它们在不同过程中将采用什么值。
我认为重点是,您正在创建 4 个进程,这些进程正在执行您提供给它们的代码。它们在同一个实例中工作,但执行相同的代码。
所以也许,你做多线程,或者你使用一些if子句等来确定哪个进程应该执行哪个代码。
- 干杯