多处理:不能在文件之间共享变量



我用一个最小的例子来描述我的问题。在我的项目中,一个config文件包含一个变量param,它被所有其他模块使用:

# config.py
param = -1

configsolver中导入,CCD_4基于传递的val和来自config:的param执行计算

# solver.py
import config
def solve(val):
# some computation using val and config.param
print('solver uses param:', config.param)
return None

我的目标是对一些param和各种val进行计算。

# main.py
import multiprocessing as mp
import config, solver
val_list = [None for i in range(3)]
pool = mp.Pool(10)
config.param = 1
print('testing param: ', config.param)
results = pool.map(solver.solve, [val for val in val_list]) # multiprocessing
#results = [solver.solve(val) for val in val_list]          # basic

在使用多处理时,我得到一个输出:

testing param:  1
solver uses param: -1
solver uses param: -1
solver uses param: -1

这意味着CCD_ 9在CCD_。然而,当使用基本的循环计算时可以看到:

testing param:  1
solver uses param: 1
solver uses param: 1
solver uses param: 1

如何使用多处理获得所需的行为?请注意,param的更改不应该在config中手动完成,因为实际上我在for循环中测试了param的不同值。我在Linux上使用Python 3.6.9。谢谢

mp.Pool()启动之前,您可以覆盖config.param值,如下所示。

# main.py
import multiprocessing as mp
import config, solver
config.param = 1 # trick is that
val_list = [None for i in range(3)]
pool = mp.Pool(10)
print('testing param: ', config.param)
results = pool.map(solver.solve, [val for val in val_list]) # multiprocessing
#results = [solver.solve(val) for val in val_list]          # basic

调用mp.Pool(10)的那一刻,您创建了10个新进程;等待模式";直到你给他们一些运行的东西,但他们已经从你的过程中分叉出来了,所以对局部变量的任何更改都不会影响他们的

如果你想把信息传递给他们,你要么需要:

在调用它们时将其传递给它们(只需添加类似pool.map(solver.solve, [(val, config.param) for val in val_list]的内容,然后让solve拆分这些参数(

或者您需要使config.param成为一个变量,可以在可能使用multiprocessing.Value的进程之间共享,如下所示:

# config.py
import multiprocessing as mp
param = mp.Value("i", -1)

然后您可以访问这样的值:config.param.value

我们需要solver.py内部的getter和setter方法来确保param值的一致性

#solver.py
import config
class Solver:
def __init__(self):
self._config = config.param
@property
def config(self):
return self._config
@config.setter
def config(self, cfgval):
self._config = cfgval
def solve(self, val):
# some computation using val and config.param
print('solver uses param:', self.config)
return None

然后,您可以按照main.py中的预期对一些param和各种val执行计算。

# main.py
import multiprocessing as mp
from solver import Solver

if __name__ == '__main__':
val_list = [None for i in range(3)]
pool = mp.Pool(10)
solver = Solver()
solver.config = 1
results = pool.map(solver.solve, [val for val in val_list])  # multiprocessing

最新更新