这个问题在这里已经有答案了:

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

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

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

解决这个问题的最佳方法是什么?

有帮助吗?

解决方案

我写过关于 在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

其他提示

辅助线程可以在主线程中可靠引发的唯一异常是 KeyboardInterrupt:辅助线程执行此操作的方式是调用该函数 thread.interrupt_main(). 。没有办法将额外的信息(关于异常的原因)与引发的异常对象关联起来——后者总是只是一个简单的 KeyboardInterrupt. 。因此,您需要将该信息存放在其他地方,例如在专用实例上 队列.队列 -- 该信息可能包括辅助线程可以通过其获取的结果 sys.exc_info(), ,以及您认为有用的任何其他内容。

主线程将需要恢复该额外信息(并考虑到如果键盘中断实际上是由于用户按下 control-C 等造成的,则队列将为空,因此,使用 get_nowait 并准备好应对 Queue.Empty 例如,异常),按照您的需要格式化它,然后终止(如果所有辅助线程都在 守护进程s,当主线程终止时整个进程也终止)。

非常不幸的是,接受的答案没有回答问题。您宁愿将异常详细信息通过管道传输到队列中。请看一下: 在Python中捕获调用者线程中的线程异常

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top