代码之家  ›  专栏  ›  技术社区  ›  nikow

使用多处理时,获取堆栈跟踪的最佳方法是什么?

  •  17
  • nikow  · 技术社区  · 15 年前

    我想知道,当通过多处理模块执行的函数内部出现异常时,获取stacktrace的最佳方法是什么。下面是一个例子:

    import multiprocessing
    
    def square(x):
        raise Exception("Crash.")
        return x**2
    
    if __name__ == '__main__':
        pool = multiprocessing.Pool(processes=4)
        results = pool.map_async(square, range(5))
        for result in results.get():
            print result
    

    这张照片是:

    Traceback (most recent call last):
      File "/extra/workspace/Playground/src/multiproc/multiproc_debug.py", line 11, in <module>
        for result in results.get():
      File "/extra/Python 2.6/lib/python2.6/multiprocessing/pool.py", line 422, in get
        raise self._value
    Exception: Crash.
    

    所以没有有用的stacktrace,这很烦人。我目前的解决方案是:

    import multiprocessing
    import traceback
    
    def square(x):
        try:
            # some more code...
            raise Exception("Crash.")
        except Exception, exception:
            print exception
            traceback.print_exc()
            raise
        return x**2
    

    有没有办法在没有所有样板代码的情况下获得这种行为?如果没有,不包括此功能的原因是什么?

    编辑:可以使用样板代码的装饰器,但我不知道标准库中是否包含这样的装饰器?

    3 回复  |  直到 15 年前
        1
  •  11
  •   Ned Batchelder    15 年前

    看起来应该避免从主函数引发异常。相反,您可以捕获它,将其视为返回给主程序的值,然后在那里提升它。 Re-throwing exceptions in Python 有更多细节。

        2
  •  4
  •   guettli    9 年前

    在Python 3.4中,提供了完整的回溯。

    http://bugs.python.org/issue13831

        3
  •  2
  •   Community CDub    8 年前

    Python 2

    我制作了一个装饰器实现,如下所示。 注意 functools.wraps ,否则 multiprocessing 就会失败。

    def full_traceback(func):
        import traceback, functools
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                msg = "{}\n\nOriginal {}".format(e, traceback.format_exc())
                raise type(e)(msg)
        return wrapper
    

    例如: https://stackoverflow.com/a/43223455 .

    Python 3

    正如 罗佩奇 现在 get 方法 multiprocessing.pool.Async 返回Python 3中的完整回溯,请参阅 http://bugs.python.org/issue13831 .