并行化方法调用以修改对象

时间:2017-04-14 20:29:01

标签: python python-3.x oop parallel-processing

我有一些类的实例,我想通过调用方法来修改它们。该方法将调用一个系统命令,但需要一段时间才能返回,所以我想并行执行几个操作。我认为这将是一件非常简单的事情,但我很难过。这是一个类似于我想要完成的例子:

import os

class SquareMe():
    def __init__(self, x):
        self.val = x
    def square(self):
        os.system('sleep 10')  # I'll call a slow program
        self.val = self.val **2

if __name__ == '__main__': 
    objs = [SquareMe(x) for x in range(4)]
    for obj in objs:
        obj.square()  # this is where I want to parallelize it
    print([obj.val for obj in objs])

此代码有效(打印[0,1,4,9]),但运行需要40秒。我试图将其降低到大约10秒钟。

我已经查看了子进程和多处理模块,但据我所知,他们会在评估square()之前挑选对象,这意味着每个对象的副本都将被修改,并且原始文件将保持不变。我认为解决方案是返回自我并覆盖原始,但如果可能的话,这远非直截了当。我调查了线程,并给人的印象是我会遇到同样的问题。

我也研究过使用异步(我正在使用python 3.5)。据我所知,系统调用(包括“睡眠10”)是阻塞的,这意味着异步不会加速它。

有没有简单,优雅,pythonic的方式来做到这一点?

1 个答案:

答案 0 :(得分:0)

事实证明,一旦找到合适的代码,使用多处理并返回自我是非常简单的。这就是我最终得到的结果:

import os
import multiprocessing

class SquareMe():
    def __init__(self, x):
        self.val = x
    def square(self):
        os.system('sleep 10')  # I'll call another program, which take a while
        self.val = self.val **2
        return self

if __name__ == '__main__':
    objs = [SquareMe(x) for x in range(4)]
    pool = multiprocessing.Pool(4)
    objs = pool.map(SquareMe.square, objs)
    pool.close()
    pool.join()
    print([obj.val for obj in objs])