10

这个(非常简化的示例)工作正常(Python 2.6.6,Debian Squeeze):

from multiprocessing import Pool
import numpy as np

src=None

def process(row):
    return np.sum(src[row])

def main():
    global src
    src=np.ones((100,100))

    pool=Pool(processes=16)
    rows=pool.map(process,range(100))
    print rows

if __name__ == "__main__":
    main()

然而,经过多年被教导全球状态不好!,我所有的直觉都在告诉我,我真的很愿意写一些更接近于:

from multiprocessing import Pool
import numpy as np

def main():
    src=np.ones((100,100))

    def process(row):
        return np.sum(src[row])

    pool=Pool(processes=16)
    rows=pool.map(process,range(100))
    print rows

if __name__ == "__main__":
    main()

但当然这不起作用(挂断无法腌制某些东西)。

这里的例子很简单,但是当你添加多个“进程”函数时,每个函数都依赖于多个额外的输入......好吧,这一切都让人想起 30 年前用 BASIC 编写的东西。尝试使用类至少用适当的函数聚合状态似乎是一个明显的解决方案,但在实践中似乎并不那么容易。

是否有一些推荐的模式或风格来使用 multiprocessing.pool 以避免全局状态的扩散以支持我想要并行映射的每个功能?

经验丰富的“多处理专家”如何处理这个问题?

更新:请注意,我实际上对处理更大的数组感兴趣,因此上述对src每个调用/迭代进行腌制的变体不如将其分叉到池的工作进程中的变体。

4

1 回答 1

8

您总是可以像这样传递一个可调用对象,然后该对象可以包含共享状态:

from multiprocessing import Pool
import numpy as np

class RowProcessor(object):
    def __init__(self, src):
        self.__src = src
    def __call__(self, row):
        return np.sum(self.__src[row])

def main():
    src=np.ones((100,100))
    p = RowProcessor(src)

    pool=Pool(processes=16)
    rows = pool.map(p, range(100))
    print rows

if __name__ == "__main__":
    main()
于 2012-04-14T09:44:20.510 回答