如何避免在Python中覆盖信号处理程序?

时间:2012-08-18 11:38:15

标签: python signals

我的实验代码如下:

import signal

def hi(signum, frame):
    print "hi"

signal.signal(signal.SIGINT, hi)
signal.signal(signal.SIGINT, signal.SIG_IGN)

hi未打印,因为信号处理程序被signal.SIG_IGN覆盖。

我该如何避免这种情况?

3 个答案:

答案 0 :(得分:2)

如果您不想覆盖自己的处理程序,请检查您是否设置了一个:

if signal.getsignal(signal.SIGINT) in [signal.SIG_IGN, signal.SIG_DFL]:
    signal.signal(signal.SIGINT, hi)

根据the documentation,有些高级进程可能已经从默认值重新分配了处理程序。如果您不想覆盖它,请将None添加到信号列表中。

signal.signal(..., signal.SIG_IGN)的明显包装器将是not in测试。

在回复评论时添加了

通常不会进行链接信号处理程序,因为信号非常精细。如果我真的想这样做,我会遵循atexit的模型并注册要由你的处理程序调用的函数。

答案 1 :(得分:1)

您可以尝试检查是否已有处理程序。如果是这样,将所需的处理程序和旧处理程序放在一个调用它们的包装器函数中。

def append_signal(sig, f):

    old = None
    if callable(signal.getsignal(sig)):
        old = signal.getsignal(sig)

    def helper(*args, **kwargs):
        if old is not None:
            old(*args, **kwargs)
        f(*args, **kwargs)

    signal.signal(sig, helper)

答案 2 :(得分:0)

只需执行与C中相同的操作:

sig_hand_prev = None

def signal_handler(signum, frame):
  ...
  signal.signal(signum, sig_hand_prev)
  os.kill(os.getpid(), signum)

def install_handler(signum):
  global sig_hand_prev
  sig_hand_prev = signal.signal(signum, signal_handler)

这里的关键思想是只保存以前的处理程序,并在完成处理后再次提高它。这样,信号处理就是单个链表OOB。