【问题标题】:Differences between pool.map and pool.imap_unordered when the worker throws an exceptionWorker 抛出异常时 pool.map 和 pool.imap_unordered 的区别
【发布时间】:2014-10-09 13:21:10
【问题描述】:

假设我这样做:

import multiprocessing as mp

def f(x):
    print x
    raise OverflowError 

if __name__ == '__main__':
    pool = mp.Pool(processes=1)
    pool.map(f, range(10))
    pool.close()
    pool.join()

出来:

0
3
6
9
Traceback (most recent call last):
  File "test1.py", line 9, in <module>
    pool.map(f, range(10))
  File "/Users/usualme/anaconda/lib/python2.7/multiprocessing/pool.py", line 251, in map
    return self.map_async(func, iterable, chunksize).get()
  File "/Users/usualme/anaconda/lib/python2.7/multiprocessing/pool.py", line 558, in get
    raise self._value
OverflowError

现在我将map 替换为imap_unordered

import multiprocessing as mp

def f(x):
    print x
    raise OverflowError 

if __name__ == '__main__':
    pool = mp.Pool(processes=1)
    for _ in pool.imap_unordered(f, range(10)):
        pass
    pool.close()
    pool.join()

出来:

0
1
2
3
4
5
Traceback (most recent call last):
  File "test0.py", line 9, in <module>
6
7
    for _ in pool.imap_unordered(f, range(10)):
8
  File "/Users/usualme/anaconda/lib/python2.7/multiprocessing/pool.py", line 659, in next
9
    raise value
OverflowError

我的问题:

  • map:为什么会从 0 跳到 3、6 和 9?
  • forimap_unordered:这次怎么一直到9?有什么不同?

【问题讨论】:

    标签: python python-2.7 multiprocessing


    【解决方案1】:

    mapimapimap_unordered 处理中的数据。就其性质而言,它们准备将这些块并行提交给多个进程。

    for imap_unordered:这次怎么一直到9?什么是 不一样?

    对于imap(大概是imap_unordered),the default chunksize is 1。因此,f 实际上将开始对所有值执行。

    您可以通过传递 chunksize 参数来检查此行为。如果您将chunksize=1 提供给map,您将获得与其他示例类似的行为。

    对于地图:为什么会从 0 跳到 3、6 和 9?

    虽然文档中没有提到,但似乎map 的默认chunksize 是“更智能”的。在这里,块大小看起来是 3,所以块将是[[0,1,2],[3,4,5],[6,7,8],[9]]

    我不知道为什么当你只有一个进程时这一切仍然会发生,但我的猜测是实现会在检查它们之前聚合所有结果。异常,IIRC,在子进程中被捕获并通过 IPC 序列化 - 它们是任何其他的结果。

    【讨论】:

    • chunksize 算法map 使用的是:chunksize, extra = divmod(len(&lt;iterable passed to map&gt;), &lt;processes in pool&gt; * 4)); if extra: chunksize +=1。所以在这种情况下:divmod(10, 1*4) == (2, 2),所以chunksize 为 3。
    猜你喜欢
    • 2014-10-23
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 1970-01-01
    相关资源
    最近更新 更多