我很擅长使用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,尽管没有明确)。
我是否必须立即创建和关闭游泳池两次,或者我可以只执行一次?
答案 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()
您通常应该包含minimal, complete, verifiable example。您的示例无法运行。更糟糕的是,它包含许多无关的特定于域的代码(例如P
,V
,Dynamics
),这些代码阻止其他人尝试运行您的示例。
说明观察到的代码行为(例如输出错误,运行时错误等)和所需行为。
将Pool
导入为ThreadPool
会很困惑,因为线程和进程是different,但却有非常相似的API。
答案 1 :(得分:1)
您不必实例化多个池。在致电pool.map(...)
之前,您可以多次致电pool.close()
。只有在没有更多任务要提交到池中时才调用pool.close()
。
但需要注意的是pool.map(...)
是一个阻塞调用 - 在提交给池的所有任务完成之前,它不会返回。这可能对您的目的而言效率低下 - 在池工作时您可能希望进行后台工作,例如收集/提交更多任务。您可以使用pool.map_async(...)
,但您的代码会变得更复杂。
旁注:我会小心你的命名。 multiprocessing.Pool不是线程池。这是一个子进程池。线程池和进程池是不同的动物,有自己的考虑因素。
事实上,你可能会发现你真的想要一个自制的线程池,如果你的处理大部分都是numpy(C扩展,GIL发布,对解释器级别的争用没有太多担心,即使是繁重的处理, threading =较少的IPC开销和系统资源要求等)。