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

Mat*_*ner 16 python multithreading exception-handling systemexit

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

如果我通过创建线程threading.Thread然后抛出未处理的异常,则终止这些线程.我希望使用堆栈跟踪保留缺省打印的异常详细信息,但也要关闭整个过程.

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

最好的方法是什么?

Ned*_*der 16

我写过关于在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()
Run Code Online (Sandbox Code Playgroud)

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

if self.exc_info:
    raise self.exc_info[1], None, self.exc_info[2]
return self.result
Run Code Online (Sandbox Code Playgroud)

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

Python 3.x:

try:
    self.result = self.do_something_dangerous()
except Exception as e:
    import sys
    self.exc_info = sys.exc_info()
Run Code Online (Sandbox Code Playgroud)

并在你的主线程上:

if self.exc_info:
    raise self.exc_info[1].with_traceback(self.exc_info[2])
return self.result
Run Code Online (Sandbox Code Playgroud)

  • 我怀疑问题不在于知道如何重新引发异常的机制,而在于何时重新引发异常,即主线程如何知道有一个异常等待重新引发? (2认同)

Ale*_*lli 11

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

主线程将需要恢复该额外信息(并且考虑到如果键盘中断实际上是由于用户点击控制-C等而队列将为空,那么,使用get_nowait并准备好处理Queue.Empty异常,例如),根据需要格式化它,并终止(如果所有辅助线程都是守护进程,则整个进程在主线程终止时终止).


Chr*_*phe 5

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