python:并行调用多个实例的方法

时间:2017-11-30 15:51:07

标签: python python-3.x multiprocessing

我试图在多个实例上并行调用相同的方法,其中实例引用同一个对象。

对此混淆声明感到抱歉。

具体来说,我想将以下for循环更改为并行执行:

for i in range(len(instances)):#instances is a list of instances
   instances[i].do_some_computation_over_a_dataset()

有可能吗?

请注意未来的读者:

上面的代码不是迭代Python中的一组实例的方法。这是如何以顺序(即非并行)方式迭代:

for i in instances:
    i.do_some_computation_over_a_dataset()

2 个答案:

答案 0 :(得分:2)

好的,我们来做吧。首先是代码(multiprocessing docs):

In [1]: from multiprocessing import Process

In [2]: def f():
   ...:     print(1)
   ...:     for i in range(100):
   ...:         # do something
   ...:         pass
   ...:

In [3]: p1 = Process(target=f)

In [4]: p1.start()

1
In [5]: p2 = Process(target=f)

In [6]: p2.start()

1
In [7]: import time

In [8]: def f():
   ...:     for i in range(100):
   ...:         print(i)
   ...:         # do something
   ...:         time.sleep(1)
   ...:         pass
   ...:
In [9]: p1 = Process(target=f)
In [9]: p1 = Process(target=f)

In [10]: p1.start()

0
In [11]: p2 1
= Process(target=f)2
3
4
5
In [11]: p2 = Process(target=f)

In [12]: 6
p2.7
start8
In [12]: p2.start()

0
In [13]: 9

这是一个如何并行调用函数的示例。从In [10]: p1.start()开始,您可以看到输出混乱,因为当我们运行程序p2时,程序p1并行运行。

在Python脚本中运行程序时,您希望确保脚本仅在所有程序成功执行后结束。你可以通过

来做到这一点
def multi_process(instance_params, *funcs):
   process = []
   for f in funcs:
       prog = Process(target=f, args=instance_params)
       prog.start()
       process.append(prog)
   for p in process:
       p.join()

multi_process(params, f, f)
由于GIL,Python没有C ++或Java那样的多线程支持。 Read about it here。虽然如果你的程序执行更多I / O操作然后CPU密集型任务,那么你可以使用多线程。为了执行CPU密集型任务,建议使用多处理。

评论@ytutow询问工作人员进程之间有什么区别。来自Pymotw

  

Pool类可用于管理固定数量的worker   可以分解要完成的工作的简单案例   独立地在工人之间分配。

     

收集作业的返回值并将其作为列表返回。

     

池参数包括进程数和函数   在启动任务过程时运行(每个孩子调用一次)。

您可以将游泳池用作:

def your_instance_method(instance):
   instances.do_some_computation_over_a_dataset()

with Pool(3) as p:
    instances = [insatnce_1, instance_2, instance_3]
    print(p.map(your_instance_method, instances))

关于正确数量的工人,它的通用建议是拥有2 * cpu_cores工人数。

答案 1 :(得分:2)

此代码似乎显示了for循环和Pool之间的区别,在不同的实例上调用方法:

from multiprocessing import Pool

instances = ['a','ab','abc','abcd']


def calc_stuff(i):
    return len(i)


if __name__ == '__main__':

    print('One at a time')
    for i in instances:
        print(len(i))

    print('Use Pool')
    with Pool(4) as pool:
        print(pool.map(calc_stuff, instances))

请注意使用if __name__ == '__main':

这将每个进程分开。

输出:

One at a time
1
2
3
4
Use Pool
[1, 2, 3, 4]