在Python中使用池

时间:2015-07-31 17:08:35

标签: python pool python-multiprocessing

我很擅长使用Python进行多处理,而我正试图了解如何正确使用Pool。我有一些看起来像这样的代码:

import numpy as np
from multiprocessing.dummy import Pool as ThreadPool
... 


pool = ThreadPool(15)

arb = np.arange(0,len(np.concatenate((P,V),axis=0)),1)

F = pool.map(tttt,arb)

pool.close()
pool.join()

NT = 1000

for test in range(0,NT):
    (P,V) = Dynamics(P,V,F)

    pool = ThreadPool(15)

    F = pool.map(tttt,arb)

    pool.close()
    pool.join() 

...

tttt和Dynamics是之前定义的两个函数。我想使用Pool能够使用tttt同时计算很多值,但我也想更新我用于那些计算的值(tttt取决于P和V,尽管没有明确)。

我是否必须立即创建和关闭游泳池两次,或者我可以只执行一次?

2 个答案:

答案 0 :(得分:3)

简单回答

似乎您希望在for循环的每次迭代中使用一个进程池。您使用Pool.map时所做的事情比您需要的更复杂,但是您对.join().close()的调用表明您宁愿使用Pool.map_async。这是一个简单的例子:

import numpy as np
from multiprocessing import Pool
from time import sleep

def print_square(x):
    sleep(.01)
    print x**2

if __name__=='__main__':

    for k in range(10):
        pool = Pool(3)
        arb = np.arange(0,10)
        pool.map_async(print_square,arb)
        pool.close()
        pool.join()

一般性评论

  1. 您通常应该包含minimal, complete, verifiable example。您的示例无法运行。更糟糕的是,它包含许多无关的特定于域的代码(例如PVDynamics),这些代码阻止其他人尝试运行您的示例。

  2. 说明观察到的代码行为(例如输出错误,运行时错误等)和所需行为。

  3. Pool导入为ThreadPool会很困惑,因为线程和进程是different,但却有非常相似的API。

答案 1 :(得分:1)

您不必实例化多个池。在致电pool.map(...)之前,您可以多次致电pool.close()。只有在没有更多任务要提交到池中时才调用pool.close()

但需要注意的是pool.map(...)是一个阻塞调用 - 在提交给池的所有任务完成之前,它不会返回。这可能对您的目的而言效率低下 - 在池工作时您可能希望进行后台工作,例如收集/提交更多任务。您可以使用pool.map_async(...),但您的代码会变得更复杂。

旁注:我会小心你的命名。 multiprocessing.Pool不是线程池。这是一个子进程池。线程池和进程池是不同的动物,有自己的考虑因素。

事实上,你可能会发现你真的想要一个自制的线程池,如果你的处理大部分都是numpy(C扩展,GIL发布,对解释器级别的争用没有太多担心,即使是繁重的处理, threading =较少的IPC开销和系统资源要求等)。