我的实验代码如下:
import signal
def hi(signum, frame):
print "hi"
signal.signal(signal.SIGINT, hi)
signal.signal(signal.SIGINT, signal.SIG_IGN)
hi
未打印,因为信号处理程序被signal.SIG_IGN
覆盖。
我该如何避免这种情况?
答案 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。