multiprocessing.Pool:map_async和imap有什么区别?

我试图学习如何使用Python的multiprocessing包,但我不明白map_asyncimap之间的区别。 我注意到map_asyncimap都是asynchronous执行的。 那么我应该什么时候使用一个呢? 而我应该如何检索由map_async返回的结果?

我应该用这样的东西吗?

 def test(): result = pool.map_async() pool.close() pool.join() return result.get() result=test() for i in result: print i 

imap / imap_unorderedmap / map_async之间有两个关键区别:

  1. 他们消耗你传递给他们的迭代的方式。
  2. 他们将结果返回给您的方式。

map通过将iterable转换为一个列表(假设它不是一个列表),将它分解成块,然后将这些块发送到Pool的工作进程,从而消耗你的迭代。 将迭代器分成块可以比在一次处理一个项目的迭代器中传递每个项目更好 – 特别是如果迭代器很大。 然而,将迭代器转换为一个列表以将其分块可能具有非常高的内存成本,因为整个列表将需要保存在内存中。

imap不会把你给它的iterable转换成列表,也不会把它分成块(默认情况下)。 它将一次遍历可迭代的一个元素,并将它们分别发送给工作进程。 这意味着你不需要把整个迭代转换成列表的内存命中,但是这也意味着对于大的迭代,性能比较慢,因为缺less分块。 然而,这可以通过传递大于默认值1的chunksize参数来缓解。

imap / imap_unorderedmap / map_async之间的另一个主要区别是,在imap / imap_unordered ,只要准备就绪,就可以开始接收工作人员的结果,而不必等待所有结果完成。 使用map_async ,一个AsyncResult会立即返回,但是直到所有的处理都被处理map_async ,你才能真正的从这个对象中获取结果。在这些点上,它会返回与map相同的列表( map实际上是作为map_async(...).get()内部实现的map_async(...).get() )。 没有办法得到部分结果; 你要么有完整的结果,要么没有。

imapimap_unordered都会立即返回迭代。 使用imap ,一旦准备就绪,结果将从迭代中放弃,同时仍然保持input迭代的顺序。 使用imap_unordered ,只要准备就绪,结果将立即生成,而不pipeinput迭代的顺序如何。 所以,说你有这个:

 import multiprocessing import time def func(x): time.sleep(x) return x + 2 if __name__ == "__main__": p = multiprocessing.Pool() start = time.time() for x in p.imap(func, [1,5,3]): print("{} (Time elapsed: {}s)".format(x, int(time.time() - start))) 

这将输出:

 3 (Time elapsed: 1s) 7 (Time elapsed: 5s) 5 (Time elapsed: 5s) 

如果你使用p.imap_unordered而不是p.imap ,你会看到:

 3 (Time elapsed: 1s) 5 (Time elapsed: 3s) 7 (Time elapsed: 5s) 

如果你使用p.map或者p.map_async().get() ,你会看到:

 3 (Time elapsed: 5s) 7 (Time elapsed: 5s) 5 (Time elapsed: 5s) 

所以,通过map_async使用imap / imap_unorderedmap_async是:

  1. 你的iterable足够大,把它转换成列表会导致你用完/使用太多的内存。
  2. 您希望能够在全部完成之前开始处理结果。