使用多处理池的并行处理循环

时间:2013-12-26 18:48:44

标签: python python-2.7 parallel-processing multiprocessing

我想并行处理一个大的for循环,从我读过的最好的方法是使用Python标准的多处理库。

我有一个大约40,000个对象的列表,我想在一个单独的类中并行处理它们。在单独的课程中这样做的原因主要是因为我读了here

在一个类中,我拥有列表中的所有对象,并通过multiprocessing.Pool和Pool.map函数,我希望通过使每个对象通过另一个类并返回一个值来执行并行计算。

# ... some class that generates the list_objects
pool = multiprocessing.Pool(4)
results = pool.map(Parallel, self.list_objects)

然后我有一个类,我想处理pool.map函数传递的每个对象:

class Parallel(object):
    def __init__(self, args):
        self.some_variable          = args[0]
        self.some_other_variable    = args[1]
        self.yet_another_variable   = args[2]
        self.result                 = None

    def __call__(self):
        self.result                 = self.calculate(self.some_variable)

我有一个调用方法的原因是由于我之前链接的帖子,但我不确定我是否正确使用它,因为它似乎没有效果。我没有得到生成的self.result值。

有什么建议吗? 谢谢!

2 个答案:

答案 0 :(得分:3)

Use a plain function, not a class,如果可能的话。只有在明显有利的情况下才使用课程。

如果你真的需要使用一个类,那么给定你的设置,传递一个Parallel实例:

results = pool.map(Parallel(args), self.list_objects)

由于实例具有__call__方法,因此实例本身是可调用的,就像函数一样。


顺便说一下,__call__需要接受另一个参数:

def __call__(self, val):

因为pool.map基本上要并行调用

p = Parallel(args)
result = []
for val in self.list_objects:
    result.append(p(val))

答案 1 :(得分:2)

Pool.map只是并行应用函数(实际上是可调用的)。它没有对象或类的概念。由于您传递了一个类,因此只需调用__init__ - __call__永远不会执行。您需要从__init__明确调用它或使用pool.map(Parallel.__call__, preinitialized_objects)