没有看到实际的代码,我只能概括地回答。但是有两种通用的解决方案。
首先,不要使用acallback
并忽略AsyncResult
s ,而是将它们存储在某种集合中。然后,您可以使用该集合。例如,如果您希望能够使用该函数作为键来查找该函数的结果,则只需dict
使用以下函数创建一个键:
def in_parallel(funcs):
results = {}
pool = mp.Pool()
for func in funcs:
results[func] = pool.apply_async(func)
pool.close()
pool.join()
return {func: result.get() for func, result in results.items()}
另外,您可以更改回调函数以按键将结果存储在集合中。例如:
def in_parallel(funcs):
results = {}
pool = mp.Pool()
for func in funcs:
def callback(result, func=func):
results[func] = result
pool.apply_async(func, callback=callback)
pool.close()
pool.join()
return results
我将函数本身用作键。但是,您想使用索引来代替,这很容易。您拥有的任何值都可以用作键。
同时,您链接的示例实际上只是对一堆参数调用相同的函数,等待所有参数完成,然后以任意顺序将结果以可迭代的方式保留。imap_unordered
确实是这样,但是简单得多。您可以用以下代码替换链接代码中的整个复杂的东西:
pool = mp.Pool()
results = list(pool.imap_unordered(foo_pool, range(10)))
pool.close()
pool.join()
然后,如果您希望结果按其原始顺序而不是任意顺序排列,则可以切换到imap
或map
代替。所以:
pool = mp.Pool()
results = pool.map(foo_pool, range(10))
pool.close()
pool.join()
如果您需要类似但又太复杂以至于无法融入该map
范式的内容,concurrent.futures
则可能会使您的生活比轻松multiprocessing
。如果您使用的是Python 2.x,则必须安装backport。但是,然后您可以完成用AsyncResult
s或callback
s(或map
)完成的工作,例如将一大堆期货组成一个大期货。请参阅链接文档中的示例。
最后一点:
如果您无法修改函数,则可以随时对其进行包装。例如,假设我有一个返回数字平方的函数,但是我试图构建一个将数字异步映射到其平方的字典,所以我也需要将原始数字作为结果的一部分。这很容易:
def number_and_square(x):
return x, square(x)
现在,我可以apply_async(number_and_square)
代替square
而获得所需的结果。
在上面的示例中,我没有这样做,因为在第一种情况下,我是从调用方将密钥存储到集合中的,而在第二种情况下,我将其绑定到了回调函数中。但是,将它们绑定到函数周围的包装就像这两个函数一样容易,并且在这两个函数都不存在的情况下可能是合适的。