Pool.map中的怪异异常传播

时间:2019-04-11 09:21:16

标签: python-3.x exception python-multiprocessing pathos

更新:最后可能会提到(目前还不太确定)解决方案。

我一直在努力寻找为什么Pool工人中引发的异常没有传播的原因,即它正在默默地继续进行。我在代码中添加了很多异常,以识别最终可能在何处捕获并发现了奇怪的行为。

我有一个课程,例如:

class Pipeline:
    def __call__(self, **kwargs):
        raise ValueError()
        for module in self.modules:
            print("Pipeline: call module: %s" % str(module))
            # raise BaseException()
            raise ValueError()
            o = module(**kwargs)
            kwargs.update(o)
        return o, kwargs

Pool中调用了哪些实例(实际上是pathos.ProcessingPool而不是multiprocessing.Pool,不确定在这种情况下它可能会发生什么变化),即

from pathos.multiprocessing import ProcessingPool as Pool

with Pool(processes=n_thread) as pool:
   pool.map(run_exp_args, [...])

def run_exp_args([...]):
    [...]
    p = Pipeline(...)
    o, k = p(**kwargs)

如您所料,这会在进入循环之前引发ValueError,在Pipeline.__call__(由跟踪的行号确认)中,它将停止程序并显示相关的跟踪。

奇怪的是,如果我首先对此ValueError进行评论(但将其保留在循环中),则异常不会传播,只会被忽略。

现在,如果我通过取消注释右上方的行来引发BaseException,则会引发此异常,我会看到跟踪,不会停止整个程序。 我一直在尝试n_thread=1,以确保我的输出相关。

print之前的raise有所不同...(删除它最终解决了问题) 如果我删除循环中的打印件,则会显示ValueError,并停止程序。

所以基本上:

class Pipeline:
    def __init__(self, *args):
        self.modules = [*args]

    def __call__(self, **kwargs):
        for module in self.modules:
            print()      
            raise ValueError()                     
            o = module(**kwargs)
            kwargs.update(o)                       
        return o, kwargs

运行时没有错误

class Pipeline:
    def __init__(self, *args):
        self.modules = [*args]

    def __call__(self, **kwargs):
        for module in self.modules:
            raise ValueError()                     
            o = module(**kwargs)
            kwargs.update(o)                       
        return o, kwargs

失败(这就是我想要的!)。

实际上,真正的逻辑发生在o = module(...)调用中,该调用包含很多指令,包括print和未引发的异常。

这是一个非常烦人的问题,因为我不能在并行模式下信任我的程序,因此我必须在没有Pool的情况下运行它(特别是因为有重要的assert被忽略了)。

您有什么想法吗?


注释: (1)提出BaseException的想法来自Exception thrown in multiprocessing Pool not detected,但是线程并没有真正解决一个真正的问题:为什么两个ValueError的行为不同?


解决方案(也许)

使用:https://gist.github.com/oseiskar/dbd38098038df8944e21b41c42668440似乎可以解决我的问题。

0 个答案:

没有答案