在主线程中的线程中引发未处理的异常?

2024-05-18 09:39:58 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

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

最好的办法是什么?


Tags: 对象答案堆栈过程详细信息手动线程thread
3条回答

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

在工作线程上执行此操作(Python2.x,请参阅下面的Python3.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

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

Python3.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:辅助线程的方法是调用函数^{}。无法将额外的信息(关于异常原因)与引发的异常对象关联起来——后者总是一个简单的KeyboardInterrupt。因此,您需要将这些信息保存在其他地方,例如在Queue.Queue的一个专用实例上——这些信息可能包括辅助线程通过sys.exc_info()可以获得的结果,以及您发现有用的任何其他信息。

主线程将需要恢复额外的信息(并考虑到如果键盘中断实际上是由于用户点击control-C或类似命令造成的,则队列将为空,因此,请使用get_nowait,并准备好处理Queue.Empty异常),然后根据需要格式化它,和terminate(如果所有次线程都是daemons,则整个进程在主线程终止时终止)。

很不幸,接受的答案没有回答这个问题。您宁愿将异常详细信息管道化到队列中。请看一下:Catch a thread's exception in the caller thread in Python

相关问题 更多 >