Python中的默认信号处理方式

4
我想注册一个自定义信号处理程序,它会执行一些操作,然后继续正常的信号处理,特别是针对 SIGTERM 信号。
Python 没有注册 SIGTERM 处理程序(Python: What is the default handling of SIGTERM?),所以在我执行自己的自定义处理后,如何继续使用操作系统的正常 SIGTERM 处理?
def my_handler(self, signum, frame):
    do_something()
    # What do I do here to raise to the OS?

signal.signal(signal.SIGTERM, my_handler)
2个回答

3
如果致命信号的先前状态是默认值,那么你能做的最好的办法就是恢复该状态并重新引发该信号。
这至少会导致进程异常终止,使得其父进程可以知道哪个信号导致了它的退出(os.WIFSIGNALED)。如果致命信号有一个"额外操作",比如生成核心文件,那么这种模拟就不会完美。
orig_handler = signal.signal(signal.SIGTERM, my_handler)

def my_handler(signum, frame):
  do_something()

  # Now do whatever we'd have done if
  # my_handler had not been installed:

  if callable(orig_handler):              # Call previous handler
    orig_handler(signum, frame)
  elif orig_handler == signal.SIG_DFL:    # Default disposition
    signal.signal(signum, signal.SIG_DFL)
    os.kill(os.getpid(), signum)
                                          # else SIG_IGN - do nothing

将上述信号重新引发并不够细致,因为某些信号会停止进程(例如 SIGTSTP),或者默认被忽略(SIGCHLD、SIGURG)。

问题在于,Python没有针对SIGTERM的信号处理程序。 - C_Z_
如果 @C_Z_ 没有设置信号处理程序,那么信号处理程序将是默认的 SIG_DFL,你可以按照上述描述进行处理。(上述方法也适用于在你的信号处理程序设置之前安装了自己的处理程序的程序。) - pilcrow

-1

在此之前,你需要保存默认值,如下:

def my_handler(self, signum, frame):
    global original_sig_handler # Doesn't really matter if you do it as global or something else, you just need  the function to get here
    do_something()
    original_sig_handler()

original_sig_handler = signal.getsignal(signal.SIGINT) # this return the function that called by handling the signal
signal.signal(signal.SIGINT, my_handler)

编辑:

这个方法不能用于 sigterm,但可以用于其他几个信号。

对于 sigterm,Python 可以使用 sys.exit 等方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接