Python 多处理挂起

sad*_*asd 5 python multiprocessing

下面是一分钟。可重现的代码:

import multiprocessing

class E(Exception):
    def __init__(self, a1, a2):
        Exception.__init__(self, '{}{}'.format(a1, a2))

def f(_):
    raise E(1, 2)

multiprocessing.Pool(1).map(f, (1,))
Run Code Online (Sandbox Code Playgroud)

这给出了以下错误:

Exception in thread Thread-5:
Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python3.7/multiprocessing/pool.py", line 496, in _handle_results
    task = get()
  File "/usr/lib/python3.7/multiprocessing/contrnection.py", line 251, in recv
    return _ForkingPickler.loads(buf.getbuffer())
TypeError: __init__() missing 1 required positional argument: 'a2'
Run Code Online (Sandbox Code Playgroud)

有任何解决这个问题的方法吗?这里提到了类似的问题:https ://bugs.python.org/issue39751

Boo*_*boo 0

我尝试通过定义pickle函数__getstate__和来解决这个问题__getstate__,但它们甚至没有被调用。但是,以下内容应该回避该问题,直到该问题(我确实认为是该类的问题reduction.ForkingPickler)得到解决:

import multiprocessing

class E(Exception):
    def __init__(self, *args):
        if len(args) == 2:
            # Normal instantiation:
            Exception.__init__(self, '{}{}'.format(args[0], args[1]))
        else:
            # We are being pickled by the reduction.ForkingPickler:
            assert(len(args) == 1)
            Exception.__init__(self, args[0])

def f(_):
    raise E(1, 2)

if __name__ == '__main__': # Required for Windows
    try:
        multiprocessing.Pool(1).map(f, (1,))
    except E as e:
        print('Got E Exception:', e)
Run Code Online (Sandbox Code Playgroud)

印刷:

Got E Exception: 12
Run Code Online (Sandbox Code Playgroud)