Skip to main content
 首页 » 编程设计

python之多处理模块映射方法中的赋值(Python)

2025年05月04日11xiaohuochai

我的问题是关于 Python 的多处理模块。 在最简单的形式中,我的问题是以下代码的奇怪行为:

import numpy as np 
from multiprocessing import Pool 
 
x = np.random.random(100) 
y = np.random.random(100) 
y2 = y[:] 
 
def I(i): 
    y[i] = x[i] 
 
pool = Pool() 
pool.map(I,range(100)) 

执行后,我希望y = x。 然而,我们得到 y = y2。 (作业不起作用。) 为什么会这样? 计算 f(x[i]) 并将其分配给 y[i] 的最佳方法是什么?

请您参考如下方法:

如果您考虑一下 Pool 用来完成您的工作的进程之间正在同步什么,您所看到的行为就不足为奇了。只有 I 函数的参数和返回值在您当前的代码中是同步的,因此 x 和 y 保持其原始值是有意义的在调用过程中。

我怀疑您当前的代码是一个最小的测试用例,这很麻烦,因为使用 Pool.map 将一个数组复制到另一个数组并没有真正有意义的实现。这是一个简单的解决方案,但我不确定它是否适用于您的实际任务:

import numpy as np 
from multiprocessing import Pool 
 
def I(v): 
    return v 
 
if __name__ == "__main__":  # this boilerplate is required on on Windows 
    x = np.random.random(100) 
    y = np.random.random(100) 
 
    pool = Pool() 
    y[:] = pool.map(I, x) 
 
    print(x == y) # [True, True, True, ...] 

这会将 x 的每个值传递给另一个进程(没有对其进行任何处理),结果值被传回并分配给 y(pool.map返回一个列表)。这很愚蠢。

稍微复杂一点的方法可能会将 x 复制到工作进程,使用 Pool 中的 initializer 和 initargs 参数 构造函数。这是一个这样做的例子:

import numpy as np 
from multiprocessing import Pool 
 
def I(index): 
    return x[index] 
 
def setup(value): 
    global x 
    x = value 
 
if __name__ == "__main__": 
    x = np.random.random(100) 
    y = np.random.random(100) 
 
    pool = Pool(initializer=setup, initargs=(x,)) 
    y[:] = pool.map(I, range(100)) 
 
    print(x == y) # [True, True, True, ...] 

请注意,x 仅以一种方式复制。如果我要修改它的值,则更改不会在进程之间同步。

如果您的任务确实需要同步访问源数组和目标数组,您可以尝试使用 multiprocessing.Array。我对它没有任何直接经验,但应该可以用它自己的同步版本替换 y。不幸的是,我怀疑同步会减慢你的程序,所以除非你真的需要,否则不要这样做!