Python多处理:共享内存和pickle问题

时间:2015-08-13 07:39:50

标签: python multiprocessing

我过去已经做过一些多处理,但这一次,我无法找到解决方法。

我知道如果它们位于模块的顶层,我只能腌制功能。到目前为止,这一直运行良好,但现在我必须在一个实例中使用共享内存,我没有看到将函数移动到顶层的方法。

考虑一下

import numpy as np
import multiprocessing
from itertools import repeat

class Test:

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def my_task(self):

        # Create process pool
        p = multiprocessing.Pool(4)

        # Create shared memory arrays
        share1 = multiprocessing.Array("d", self.x, lock=False)
        share2 = multiprocessing.Array("d", self.y, lock=False)

        def mp(xc, yc, c):

            # This is just some random weird statement
            foo = np.sum(share1) + np.sum(share2) +xc + yc + c
            return foo


        def mp_star(args):
            return mp(*args)

        # Define some input for multiprocessing
        xs = [1,2,3,4,5]
        ys = [5,6,7,8,9]
        c = 10

        # Submit tasks
        result = p.map(mp_star, zip(xs, ys, repeat(c)))

        # Close pool
        p.close()

        return result



# Get some input data
x = np.arange(10)
y = x**2

# Run the thing
cl = Test(x=x, y=y)
cl.my_task()

您可以看到我需要从实例本身访问共享数据。出于这个原因,我将多处理部分放在方法'my_task'中。出于这个原因,我得到了典型的泡菜错误

_pickle.PicklingError: Can't pickle <function Test.my_task.<locals>.mp_star at 0x10224a400>: attribute lookup mp_star on __main__ failed

我已经知道了。我无法将多处理任务移到顶层,因为我需要访问共享数据。另外,我希望保持较低的依赖性数量,因此我需要使用内置的多处理库。

我希望代码有意义。那么,如何在多处理中使用实例的共享内存空间呢?有没有办法将功能移到顶层?

1 个答案:

答案 0 :(得分:2)

由于唯一可以腌制的功能是顶级功能(请参阅documentation进行挑选)而multiprocessing想要腌制它,因此您将其置于顶层。你只需要重新修改你的要求。

例如,你有函数的参数,为什么不提供共享数据?或者你可以将共享数据放在一个可pickle的实例中并使函数处于顶层(你仍然可以为顶级函数提供一个类实例)。

例如,如果您想将共享数据放在一个实例中,您可以简单地在顶层定义方法,就好像它是一个普通方法(但将定义放在顶层):

def fubar(self):
    return self.x

class C(object):
     def __init__(self, x):
          self.x = x

     foo = fubar

c = C()

现在你可以挑剔fubar。您可以将其称为c.foo()fubar(c),但您只能将其称为pickle.dumps(fubar),因此当它被打开并调用时,它会在以后的方式中被调用,因此您必须提供self参数以及p.map中的其他参数(即p.map(mp_star, zip(repeat(self), xs, ys, repeat(c)))。您当然要确保self也是可以选择的。