让Python线程支持excepthook
Python #excepthook2012-11-14 22:48
在游戏中,一般会在主线程开始时,设置一个 excepthook,来对程序异常进行特定处理。
每个线程都有自己的栈,只要在发生异常时,能够把自己的调用栈和异常的相关信息,发给特定的异常处理函数(比如用户自定义的函数)处理,就可以实现 excepthook。理论上任何语言实现的线程,都可以实现 excepthook,只是对线程的异常捕获和 excepthook 的实现有要求。在 excepthook 实现中,如果有对资源(比如日志文件)和全局变量的访问,需要做好线程互斥处理。在工作线程中,当发生异常并逐级向上抛时,如果在最上层(工作线程的 main 函数)还没有被捕获,则线程会被异常终止;此时,设置的 excepthook 可能就无法发生作用了。
对 Python 线程而言,需要明确几点:
1,自定义的 excepthook 是赋值给 sys.excepthook 的。
2,程序启动时,bulit-in 的 sys.excepthook 会被保存在 sys.__excepthook__ 中。
3,当工作线程发生异常并被捕获时,如果有用户自定义的 excepthook,就应该交由该函数处理。
再来看 Python 库中 threading.py 的实现,在 Thread.__bootstrap_inner() 函数中,调用 run() 后捕捉的异常,没有对用户自定义的 excepthook 进行判断,也就导致了 Python 线程的 excepthook 无法生效。如果把代码改为如下(...... 表示保持原来的代码不变):
try: self.run() except SystemExit: ...... except: ...... if _sys: if id(_sys.excepthook) != id(_sys.__excepthook__): exc_type, exc_value, exc_tb = self.__exc_info() _sys.excepthook(exc_type, exc_value, exc_tb) else: _sys.stderr.write("Exception in thread %s: %s " % (self.getName(), _format_exc())) else: ...... # http://yige.org则在线程中发生异常时,预设的 excepthook 就可以正常生效了。
相关文章
- 制作python的exe可执行程序 2012/11/14
- Python监控引用计数 2012/11/14