我的实验代码是这样的:
import signal
def hi(signum, frame):
print "hi"
signal.signal(signal.SIGINT, hi)
signal.signal(signal.SIGINT, signal.SIG_IGN)
hi
没有被打印出来,因为信号处理程序被signal.SIG_IGN
.
我怎样才能避免这种情况?
您可以尝试检查是否已经有处理程序。如果是这样,请将您想要的处理程序和旧处理程序放在调用它们的包装函数中。
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)
如果您不想覆盖自己的处理程序,请检查您是否设置了一个:
if signal.getsignal(signal.SIGINT) in [signal.SIG_IGN, signal.SIG_DFL]:
signal.signal(signal.SIGINT, hi)
根据文档,某些高级进程可能已经从默认值中重新分配了处理程序。如果您不想覆盖它,请添加None
到信号列表中。
显而易见的包装signal.signal(..., signal.SIG_IGN)
将是一个not in
测试。
添加以回应评论
链接信号处理程序并不经常这样做,因为信号是如此精细。如果我真的想这样做,我会遵循atexit的模型并注册您的处理程序调用的函数。
只需执行与在 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。