信号处理程序中的 exit(1) 只是作为 SystemExit 被捕获,因为它没有任何内容

exit(1) in signal handler just gets caught as SystemExit as there is nothing to it

我有一个如下所示的应用程序:

while True:
    try:
        self.try_to_read_usb_device()
        break
    except:
        time.sleep(1)

我还有一个 SIGALRM 处理程序,它应该在程序卡在某处时退出该程序:

def alarm_signal_handler(signal, frame):
    # Something went wrong
    exit(1)

然而 exit(1) 只是被 try/except 捕获并被丢弃,因为这就是特定 except 所做的。

这让我很意外

在完整的应用程序中会有很多 try/except 我不认为自己添加

except SystemExit:
    exit(1)

或者他们所有人的东西。

知道我应该如何处理该用例吗?

肮脏的方式

您可以使用 os._exit 代替 sys.exit

请注意,这有明显的缺点 因为 它不会经历异常:

Exit the process with status n, without calling cleanup handlers, flushing stdio buffers, etc.

正确的方法

我建议改为更改异常处理以仅捕获从 Exception 继承的内容,因为 SystemExit 不会 继承自 Exception正是因为这个原因,才不会被误抓:

except Exception:

另见 SystemExit documentation:

This exception is raised by the sys.exit() function. It inherits from BaseException instead of Exception so that it is not accidentally caught by code that catches Exception. This allows the exception to properly propagate up and cause the interpreter to exit.

这也适用于 KeyboardInterrupt 顺便说一下 - Ctrl+C 将被 except: 捕获但不是 except Exception:.

Python 文档中的异常层次结构图对此进行了很好的说明,您可以找到 here