如果任何线程有异常,导致python退出 [英] Cause python to exit if any thread has an exception

查看:1087
本文介绍了如果任何线程有异常,导致python退出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个python3程序,该程序启动第二个线程(除主线程外)以异步处理一些事件.理想情况下,我的程序可以正常运行,并且永远不会有未处理的异常.但是事情发生了.当/如果有异常,我希望整个解释器以错误代码退出,就好像它是单个线程一样.有可能吗?

I have a python3 program that starts a second thread (besides the main thread) for handling some events asynchronously. Ideally, my program works without a flaw and never has an unhandled exceptions. But stuff happens. When/if there is an exception, I want the whole interpreter to exit with an error code as if it had been a single thread. Is that possible?

现在,如果在生成的线程上发生异常,它将打印出通常的错误信息,但不会退出.主线程一直在继续.

Right now, if an exception occurs on the spawned thread, it prints out the usual error information, but doesn't exit. The main thread just keeps going.

import threading
import time

def countdown(initial):
    while True:
        print(initial[0])
        initial = initial[1:]
        time.sleep(1)

if __name__ == '__main__':
    helper = threading.Thread(target=countdown, args=['failsoon'])
    helper.start()
    time.sleep(0.5)
    #countdown('THISWILLTAKELONGERTOFAILBECAUSEITSMOREDATA')
    countdown('FAST')

countdown最终将无法从字符串访问[0],因为它已被清空,从而导致IndexError: string index out of range错误.目的是无论主程序或辅助程序先死,整个程序都一起死,但是仍会输出堆栈跟踪信息.

The countdown will eventually fail to access [0] from the string because it's been emptied causing an IndexError: string index out of range error. The goal is that whether the main or helper dies first, the whole program dies alltogether, but the stack trace info is still output.

经过一番挖掘,我的想法是使用sys.excepthook.我添加了以下内容:

After some digging, my thought was to use sys.excepthook. I added the following:

def killAll(etype, value, tb):
    print('KILL ALL')
    traceback.print_exception(etype, value, tb)
    os.kill(os.getpid(), signal.SIGKILL)

sys.excepthook = killAll

如果主线程是最先死亡的线程,则此方法有效.但在另一种情况下却没有.这似乎是一个已知问题( https://bugs.python.org/issue1230540 ).我将在那里尝试一些解决方法.

This works if the main thread is the one that dies first. But in the other case it does not. This seems to be a known issue (https://bugs.python.org/issue1230540). I will try some of the workarounds there.

虽然示例显示了我创建的主线程和辅助线程,但我对可能正在运行别人的库以启动线程的一般情况感兴趣.

While the example shows a main thread and a helper thread which I created, I'm interested in the general case where I may be running someone else's library that launches a thread.

推荐答案

我的解决方案最终是

My solution ended up being a happy marriage between the solution posted here and the SIGKILL solution piece from above. I added the following killall.py submodule to my package:

import threading
import sys
import traceback
import os
import signal


def sendKillSignal(etype, value, tb):
    print('KILL ALL')
    traceback.print_exception(etype, value, tb)
    os.kill(os.getpid(), signal.SIGKILL)


original_init = threading.Thread.__init__
def patched_init(self, *args, **kwargs):
    print("thread init'ed")
    original_init(self, *args, **kwargs)
    original_run = self.run
    def patched_run(*args, **kw):
        try:
            original_run(*args, **kw)
        except:
            sys.excepthook(*sys.exc_info())
    self.run = patched_run


def install():
    sys.excepthook = sendKillSignal
    threading.Thread.__init__ = patched_init

然后立即运行install,然后再启动任何其他线程(由我自己创建或从其他导入的库启动).

And then ran the install right away before any other threads are launched (of my own creation or from other imported libraries).

这篇关于如果任何线程有异常,导致python退出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆