繁体   English   中英

多处理池'apply_async'似乎只调用一次函数

[英]Multiprocessing pool 'apply_async' only seems to call function once

我一直在关注文档以尝试理解多处理池。 我想出了这个:

import time
from multiprocessing import Pool

def f(a):
    print 'f(' + str(a) + ')'
    return True

t = time.time()
pool = Pool(processes=10)
result = pool.apply_async(f, (1,))
print result.get()
pool.close()
print ' [i] Time elapsed ' + str(time.time() - t)

我正在尝试使用10个进程来评估函数f(a) 我在f了一个打印声明。

这是我得到的输出:

$ python pooltest.py 
f(1)
True
 [i] Time elapsed 0.0270888805389

在我看来,函数f只被评估一次。

我可能没有使用正确的方法,但我正在寻找的最终结果是同时运行f 10个进程,并获得每个进程返回的结果。 所以我最后会列出10个结果(可能相同也可能不相同)。

关于多处理的文档非常令人困惑,要弄清楚我应该采用哪种方法并不容易,而且在我看来f应该在我上面提供的示例中运行10次。

apply_async并不意味着启动多个进程; 它只是用于在池的一个进程中使用参数调用该函数。 如果要将函数调用10次,则需要进行10次调用。

首先,请注意apply()上的文档(强调添加):

 apply(func[, args[, kwds]]) 

使用参数args和关键字参数kwds调用func。 它会阻塞,直到结果准备就绪。 给定此块,apply_async()更适合并行执行工作。 此外,func仅在池中的一个工作程序中执行。

现在,在apply_async()的文档中:

 apply_async(func[, args[, kwds[, callback[, error_callback]]]]) 

apply()方法的一种变体,它返回一个结果对象。

两者之间的区别仅在于apply_async立即返回。 您可以使用map()多次调用函数,但是如果您使用相同的输入进行调用,那么创建相同参数的列表只是为了获得正确长度的序列,这是一个小的减少。

但是,如果您使用相同的输入调用不同的函数,那么您实际上只是调用更高阶函数,并且可以使用mapmap_async()此操作:

multiprocessing.map(lambda f: f(1), functions)

除了lambda函数不是pickleable之外,所以你需要使用一个已定义的函数(参见如何让Pool.map获取lambda函数 )。 你实际上可以使用内置的apply() (而不是多处理的)(尽管它已被弃用):

multiprocessing.map(apply,[(f,1) for f in functions])

编写自己的也很容易:

def apply_(f,*args,**kwargs):
  return f(*args,**kwargs)

multiprocessing.map(apply_,[(f,1) for f in functions])

每次编写pool.apply_async(...)它都会将该函数调用委托给池中启动的其中一个进程。 如果要在多个进程中调用该函数,则需要发出多个pool.apply_async调用。

注意,还有一个pool.map (和pool.map_async )函数,它将接受一个函数和一个可迭代的输入:

inputs = range(30)
results = pool.map(f, inputs)

这些函数将函数应用于inputs iterable中的每个输入。 它尝试将“批处理”放入池中,以便负载在池中的所有进程之间相当均衡。

如果要在十个进程中运行单个代码,然后每个进程退出,则十个进程Pool可能不是正确的使用方法。

相反,创建十个Process es来运行代码:

processes = []

for _ in range(10):
    p = multiprocessing.Process(target=f, args=(1,))
    p.start()
    processes.append(p)

for p in processes:
    p.join()

multiprocessing.Pool类旨在处理进程数和作业数不相关的情况。 通常,进程数量选择为您拥有的CPU核心数,而作业数量则要大得多。 谢谢!

如果你因为任何特殊原因没有致力于Pool,我已经编写了一个围绕multiprocessing.Process的函数,它可能会为你提供帮助。 它发布在这里 ,但如果你需要,我很乐意将最新版本上传到github。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM