简体   繁体   English

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

[英]Python multiprocessing: shared memory and pickle issue

I have already done some multiprocessing in the past, but this time, I can't figure out a workaround. 我过去已经做过一些多处理,但这一次,我无法找到解决方法。

I know that I can only pickle functions if they are at the top level of a module. 我知道如果它们位于模块的顶层,我只能腌制功能。 This has always worked well so far, but now I have to work with shared memory in an instance and I don't see a way to move the function to the top level. 到目前为止,这一直运行良好,但现在我必须在一个实例中使用共享内存,我没有看到将函数移动到顶层的方法。

Consider this 考虑一下

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()

You can see that I need to access shared data from the instance itself. 您可以看到我需要从实例本身访问共享数据。 For this reason I put the multiprocessing parts within the method 'my_task'. 出于这个原因,我将多处理部分放在方法'my_task'中。 For this reason I get the typical pickle error 出于这个原因,我得到了典型的泡菜错误

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

which I already know about. 我已经知道了。 I can't move the multiprocessing tasks to the top level though since I need to access the shared data. 我无法将多处理任务移到顶层,因为我需要访问共享数据。 Also I want to keep the number of dependencies low so I need to work with the built-in multiprocessing libraries. 另外,我想保持较低的依赖数,因此我需要使用内置的多处理库。

I hope the code makes sense. 我希望代码有意义。 So, how can I use the shared memory space from an instance in multiprocessing? 那么,如何在多处理中使用实例的共享内存空间呢? Is there a way to move the functions to the top level? 有没有办法将功能移到顶层?

Since the only functions that can be pickled are those in top level (see the documentation for pickle) and multiprocessing want to pickle it you're stuck with putting it at top level. 由于唯一可以腌制的功能是顶层的(参见pickle的文档 ),而multiprocessing想要腌制它,所以你会把它放在最顶层。 You simply has to rework your requirement. 你只需要修改你的要求。

For example you've got arguments to the functions, why not supplying the shared data? 例如,你有函数的参数,为什么不提供共享数据? Or you could put the shared data in an instance that is pickleable and have the function being at top level (you can still supply a class instance to a top level function). 或者,您可以将共享数据放在可选择的实例中,并将函数置于顶级(您仍然可以向顶级函数提供类实例)。

For example if you want to put the shared data in an instance you can simply define the method at top level as if it were a normal method (but put the definition at top level): 例如,如果要将共享数据放在一个实例中,您可以简单地在顶层定义方法,就好像它是一个普通方法(但将定义放在顶层):

def fubar(self):
    return self.x

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

     foo = fubar

c = C()

now you can pickle fubar . 现在你可以fubar You can call it either as c.foo() or fubar(c) , but you can only pickle it as pickle.dumps(fubar) so when it's unpickled and called it will expect to be called in the later way so you have to supply the self parameter along with the other arguments in p.map (ie p.map(mp_star, zip(repeat(self), xs, ys, repeat(c)) ). You have of course to make sure that self is pickleable too. 你可以把它称为c.foo()fubar(c) ,但是你只能把它称为pickle.dumps(fubar)所以当它被pickle.dumps(fubar)并被调用时,它会在以后的方式被调用,所以你必须提供self参数以及p.map的其他参数(即p.map(mp_star, zip(repeat(self), xs, ys, repeat(c)) )。你当然要确保self是pickleable太。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM