当worker抛出异常时,pool.map和pool.imap_unordered之间存在差异

时间:2014-10-09 13:21:10

标签: python python-2.7 multiprocessing

说我这样做:

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

我的问题:

  • for map:为什么它从0跳到3,6和9?
  • for imap_unordered:为什么这次一直到9?有什么不同?

1 个答案:

答案 0 :(得分:2)

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

  

对于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序列化 - 它们与其他任何结果一样。