2

我的问题是关于 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] 的最佳方法是什么?

4

1 回答 1

1

Pool如果您考虑在用于完成您的工作的进程之间同步的内容,那么您所看到的行为并不令人惊讶。只有函数的参数和返回值在您当前的代码中同步,所以在调用过程中保持它们的原始值I是有意义的。xy

我怀疑您当前的代码是一个最小的测试用例,这很麻烦,因为没有真正有意义的实现将一个数组复制到另一个使用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, ...]

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

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

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只是一种复制方式。如果I要修改其值,则这些更改将不会在进程之间同步。

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

于 2013-01-09T01:58:35.797 回答