工人流程中的例外

时间:2017-04-21 12:16:18

标签: python python-multiprocessing

我在Python中使用多处理。我正在尝试确定如果工人提出异常会发生什么,所以我写了下面的代码:

def a(num):
    if(num == 2):
        raise Exception("num can't be 2")
    print(num)


    p = Pool()
    p.map(a, [2, 1, 3, 4, 5, 6, 7, 100, 100000000000000, 234, 234, 5634, 0000])

输出

3
4
5
7
6
100
100000000000000
234
234
5634
0
multiprocessing.pool.RemoteTraceback: 
"""
Traceback (most recent call last):
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 119, in worker
    result = (True, func(*args, **kwds))
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 44, in mapstar
    return list(map(*args))
  File "<stdin>", line 3, in a
Exception: Error, num can't be 2
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 260, in map
    return self._map_async(func, iterable, mapstar, chunksize).get()
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 608, in get
    raise self._value
Exception: Error, num can't be 2

如果你能看到打印的数字“2”不存在,但为什么不是数字1呢?

注意:我在Ubuntu上使用Python 3.5.2

1 个答案:

答案 0 :(得分:1)

默认情况下,Pool会创建一些等于核心数的工作人员。当其中一个工作进程死亡时,它可能会将已分配给它的工作撤消。它也可能将输出保留在永远不会被刷新的缓冲区中。

.map()的模式是处理worker中的异常并返回一些合适的错误值,因为 .map()的结果应该是与输入一对一。

from multiprocessing import Pool

def a(num):
    try:
        if(num == 2):
            raise Exception("num can't be 2")
        print(num, flush=True)
        return num
    except Exception as e:
        print('failed', flush=True)
        return e

p = Pool()
n=100
results = p.map(a, range(n))

print("missing numbers: ", tuple(i for i in range(n) if i not in results))

这是另一个提供有关how exceptions propagate in multiprocessing.map workers的详细信息的问题。