Python中SIGALRM信号处理函数内exit(1)被裸except捕获如何解决?
解决方案
方案1:替换所有裸except为捕获Exception(推荐)
Python中的裸except:会捕获所有继承自BaseException的异常,包含你遇到的SystemExit,以及KeyboardInterrupt、GeneratorExit这类非业务异常。常规业务代码需要捕获的异常全部继承自Exception类,你只需要全局搜索替换所有的裸except:为except Exception:,就能从根源上避免误吞系统级退出异常,不需要逐个给现有try分支加SystemExit处理逻辑,操作成本极低。
修改后的重试代码示例:
while True: try: self.try_to_read_usb_device() break except Exception: time.sleep(1)
修改后SystemExit会正常穿透所有业务except分支,触发进程退出。
方案2:信号处理函数改用os._exit()直接终止进程
如果你暂时没法修改全量的裸except代码,可以直接修改信号处理函数,不要用exit()/sys.exit(),改用os._exit()。该函数会直接调用操作系统接口终止进程,不会抛出任何Python异常,自然不会被except捕获吞掉:
import os def alarm_signal_handler(signal, frame): # 出现异常错误,直接终止进程不抛异常 os._exit(1)
注意:
os._exit()不会执行Python层面的清理逻辑,比如atexit注册的回调、上下文管理器的__exit__方法等,如果你有退出前要运行的清理逻辑,优先选择方案1。
内容的提问来源于stack exchange,提问作者Francois
相关产品推荐
相关产品推荐

