简体   繁体   English

'sys.excepthook' 和线程

[英]'sys.excepthook' and threading

I am using Python 2.5 and trying to use a self-defined excepthook in my program.我正在使用 Python 2.5 并尝试在我的程序中使用自定义的excepthook In the main thread it works perfectly fine.在主线程中它工作得很好。 But in a thread started with the threading module the usual excepthook is called.但是在以线程模块启动的线程中,通常会调用excepthook

Here is an example showing the problem.这是一个显示问题的示例。 Uncommenting the comment shows the desired behaviour.取消注释注释会显示所需的行为。

import threading, sys

def myexcepthook(type, value, tb):
    print 'myexcepthook'

class A(threading.Thread, object):

    def __init__(self):
        threading.Thread.__init__(self, verbose=True)
#       raise Exception('in main')
        self.start()

    def run(self):
        print 'A'
        raise Exception('in thread')            

if __name__ == "__main__":
    sys.excepthook = myexcepthook
    A()

So, how can I use my own excepthook in a thread?那么,如何在线程中使用我自己的excepthook呢?

It looks like this bug is still present in (at least) 3.4, and one of the workarounds in the discussion Nadia Alramli linked seems to work in Python 3.4 too.看起来这个错误仍然存​​在于(至少)3.4 中,并且 Nadia Alramli 链接的讨论中的一种解决方法似乎也适用于 Python 3.4。

For convenience and documentation sake, I'll post the code for (in my opinion) the best workaround here.为了方便和文档起见,我将在此处发布(在我看来)最佳解决方法的代码。 I updated the coding style and comments slightly to make it more PEP8 and Pythonic.我稍微更新了编码风格和注释,使其更加 PEP8 和 Pythonic。

import sys
import threading

def setup_thread_excepthook():
    """
    Workaround for `sys.excepthook` thread bug from:
    http://bugs.python.org/issue1230540

    Call once from the main thread before creating any threads.
    """

    init_original = threading.Thread.__init__

    def init(self, *args, **kwargs):

        init_original(self, *args, **kwargs)
        run_original = self.run

        def run_with_except_hook(*args2, **kwargs2):
            try:
                run_original(*args2, **kwargs2)
            except Exception:
                sys.excepthook(*sys.exc_info())

        self.run = run_with_except_hook

    threading.Thread.__init__ = init

It looks like there is a related bug reported here with workarounds.看起来这里报告一个相关的错误并提供了解决方法。 The suggested hacks basically wrap run in a try/catch and then call sys.excepthook(*sys.exc_info())建议的 hacks 基本上是在 try/catch 中运行,然后调用sys.excepthook(*sys.exc_info())

I just stumbled over this problem and as it turns out, it was the right time to do so.我只是偶然发现了这个问题,事实证明,现在正是这样做的时候。

New in version 3.8: threading.excepthook 3.8 新版功能: threading.excepthook

Handle uncaught exception raised by Thread.run().处理 Thread.run() 引发的未捕获异常。

The args argument has the following attributes: args 参数具有以下属性:

exc_type: Exception type. exc_type:异常类型。
exc_value: Exception value, can be None. exc_value:异常值,可以为None。
exc_traceback: Exception traceback, can be None. exc_traceback:异常回溯,可以为None。
thread: Thread which raised the exception, can be None.线程:引发异常的线程,可以是无。

I don't know why, but be aware, that unlike sys.excepthook , threading.excepthook receives the arguments as a namedtuple instead of multiple arguments.我不知道为什么,但请注意,与sys.excepthook不同, threading.excepthook将参数作为namedtuple而不是多个参数接收。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM