多处理池:map_async和imap有什么区别?

2024-04-19 20:31:11 发布

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

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

我应该用这样的东西吗?

def test():
    result = pool.map_async()
    pool.close()
    pool.join()
    return result.get()

result=test()
for i in result:
    print i

Tags: intestmapforclosegetasyncreturn
1条回答
网友
1楼 · 发布于 2024-04-19 20:31:11

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

  1. 他们消费你传递给他们的食物的方式。
  2. 他们把结果还给你的方式。

map通过将iterable转换为一个列表(假设它已经不是一个列表)、将其分成块并将这些块发送到Pool中的工作进程来消耗iterable。将iterable分为块比一次在进程之间传递iterable中的每个项要好,特别是当iterable很大时。但是,将iterable转换成一个列表以便将其分块可能会有很高的内存开销,因为整个列表都需要保存在内存中。

imap不会将给定的iterable转换为列表,也不会将其分解为块(默认情况下)。它将一次迭代iterable中的一个元素,并将每个元素发送给一个工作进程。这意味着您不需要将整个iterable转换成一个列表,但这也意味着对于大型iterable,由于缺少分块,性能会变慢。但是,可以通过传递大于默认值1的chunksize参数来缓解这种情况。

imap/imap_unorderedmap/map_async之间的另一个主要区别是,使用imap/imap_unordered,您可以在工作人员准备好后立即开始接收他们的结果,而不必等待所有工作人员完成。使用map_async,会立即返回一个AsyncResult,但在处理完所有结果之前,您实际上无法从该对象检索结果,此时它返回的列表与map所返回的列表相同(map实际上在内部实现为map_async(...).get())。没有办法得到部分结果;要么得到整个结果,要么什么都没有。

imapimap_unordered都会立即返回iterables。使用imap,结果一准备好就从iterable生成,同时仍然保留输入iterable的顺序。使用imap_unordered,无论输入iterable的顺序如何,只要结果准备好,就会立即产生结果。所以,假设你有这个:

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.mapp.map_async().get(),您将看到:

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

因此,使用imap/imap_unordered超过map_async的主要原因是:

  1. 您的iterable足够大,将其转换为列表将导致内存不足/使用过多。
  2. 您希望能够在全部完成之前开始处理结果。

相关问题 更多 >