Python中池的使用

2024-06-25 23:19:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我对使用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,尽管不是显式的)。在

我需要创建和关闭游泳池两次吗?还是可以只做一次?在


Tags: importmapcloseasnppoolthreadpooljoin
2条回答

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

但需要注意的是,pool.map(...)是一个阻塞调用,直到提交给池的所有任务都完成后才会返回。对于您的目的来说,这可能是低效的-当池正在工作时,您可能需要做后台工作,例如收集/提交更多的任务。您可以改为使用pool.map_async(...),但是您的代码会变得更加复杂。在

旁注:我会小心你的名字。A多处理.池不是线程池。它是一个子进程池。线程池和进程池是不同的野兽,它们有各自的考虑。在

事实上,如果您的处理大部分都是numpy(C扩展,GIL已发布,即使处理繁重,也不太担心解释器级别的争用,线程=更少的IPC开销和系统资源需求等),那么您可能会发现您实际上想要一个自成一体的线程池。在

简单的回答

似乎您希望在for循环的每次迭代中使用一个进程池。对于使用Pool.map,您已经使事情变得更加复杂,但是您对.join()和{}的调用表明您宁愿使用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。

相关问题 更多 >