代码之家  ›  专栏  ›  技术社区  ›  Matt Joiner

在主线程的线程中引发未处理的异常?[复制品]

  •  15
  • Matt Joiner  · 技术社区  · 15 年前

    有一些类似的问题,但没有一个提供我需要的答案。

    如果我创建线程通过 threading.Thread ,然后抛出未处理的异常,这些线程将终止。我希望使用堆栈跟踪保留异常详细信息的默认打印输出,但也会降低整个过程。

    我已经考虑到可能捕获线程中的所有异常,并在主线程对象上重新提升它们,或者可能手动执行默认的异常处理,然后引发 SystemExit 在主线程上。

    最好的方法是什么?

    3 回复  |  直到 6 年前
        1
  •  16
  •   ejm Xan    7 年前

    我写了关于 Re-throwing exceptions in Python 包括一些类似的例子。

    在您的工作线程上,您可以这样做(python 2.x,参见下面的python 3.x版本):

    try:
        self.result = self.do_something_dangerous()
    except Exception, e:
        import sys
        self.exc_info = sys.exc_info()
    

    在你的主线上,你这样做:

    if self.exc_info:
        raise self.exc_info[1], None, self.exc_info[2]
    return self.result
    

    异常将出现在主线程中,就像它在工作线程中被引发一样。

    Python 3 .x:

    try:
        self.result = self.do_something_dangerous()
    except Exception as e:
        import sys
        self.exc_info = sys.exc_info()
    

    在你的主线上:

    if self.exc_info:
        raise self.exc_info[1].with_traceback(self.exc_info[2])
    return self.result
    
        2
  •  10
  •   Cerin    6 年前

    在主线程中,辅助线程能够可靠提升的唯一例外是 KeyboardInterrupt :辅助线程通过调用函数来实现的方式 thread.interrupt_main() . 无法将额外的信息(关于异常原因)与引发的异常对象相关联——后者始终只是一个普通的 键盘中断 .因此,您需要将这些信息存储在其他地方,例如在 Queue.Queue --该信息可能包括辅助线程可以通过的结果 sys.exc_info() 当然还有其他有用的东西。

    主线程将需要恢复额外的信息(并考虑到如果键盘中断实际上是由于用户点击Control-C或类似操作造成的,那么队列将是空的,因此,使用 get_nowait 准备好应对 Queue.Empty 例如,异常),根据需要格式化它,并终止(如果所有辅助线程都是 daemon s,当主线程终止时,整个进程终止)。

        3
  •  3
  •   Community CDub    7 年前

    很不幸,被接受的答案没有回答问题。您希望将异常详细信息通过管道传输到队列中。请看一下: Catch a thread's exception in the caller thread in Python