Python多处理 - 将类方法应用于对象列表

时间:2013-04-03 14:55:43

标签: python multiprocessing

是否有一种简单的方法可以使用多处理来完成相同的操作?

for sim in sim_list:
  sim.run()

其中sim_list的元素是“模拟”对象,而run()是模拟类的一种方法, 修改对象的属性。 E.g:

class simulation:
  __init__(self):
    self.state['done']=False
    self.cmd="program"
 def run(self):
    subprocess.call(self.cmd)
    self.state['done']=True

sim_list中的所有sim都是独立的,因此策略不必是线程安全的。

我尝试了以下内容,这显然是有缺陷的,因为参数是通过深度镜检查传递的,并且没有就地修改。

from multiprocessing import Process

for sim in sim_list:
  b = Process(target=simulation.run, args=[sim])
  b.start()
  b.join()

2 个答案:

答案 0 :(得分:11)

实现目标的一种方法是让您的计算类(在您的情况下为simulation)成为Process的子类。正确初始化后,此类的实例将在不同的进程中运行,您可以从列表中设置一组,就像您想要的那样。

这是一个例子,建立在你上面写的:

import multiprocessing
import os
import random

class simulation(multiprocessing.Process):
    def __init__(self, name):
        # must call this before anything else
        multiprocessing.Process.__init__(self)

        # then any other initialization
        self.name = name
        self.number = 0.0
        sys.stdout.write('[%s] created: %f\n' % (self.name, self.number))

    def run(self):
        sys.stdout.write('[%s] running ...  process id: %s\n' 
                         % (self.name, os.getpid()))

        self.number = random.uniform(0.0, 10.0)
        sys.stdout.write('[%s] completed: %f\n' % (self.name, self.number))

然后只需创建一个对象列表并用循环开始每个对象:

sim_list = []
sim_list.append(simulation('foo'))
sim_list.append(simulation('bar'))

for sim in sim_list:
    sim.start()

运行时,您应该看到每个对象都在自己的进程中运行。不要忘记在类初始化之前调用Process.__init__(self)作为第一件事,而不是其他任何事情。

显然我在这个例子中没有包含任何进程间通信;如果您的情况需要,您将不得不补充一点(从您的问题中不清楚您是否需要它)。

这种方法适合我,我不知道有什么缺点。如果有人知道我忽略了隐藏的危险,请告诉我。

我希望这会有所帮助。

答案 1 :(得分:0)

对于那些将要处理大数据集的人,这里iterable是您的解决方案:

import multiprocessing as mp
pool = mp.Pool(mp.cpu_count())
pool.imap(sim.start, sim_list)