简体   繁体   English

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

[英]How to avoid overriding of signal handlers in Python?

My experiment code is like:我的实验代码是这样的:

import signal

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

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

hi didn't get printed, because the signal handler is overridden by signal.SIG_IGN . hi没有被打印出来,因为信号处理程序被signal.SIG_IGN覆盖。

How can I avoid this?我怎样才能避免这种情况?

You could try to check whether there is already a handler.您可以尝试检查是否已经有处理程序。 If so put your desired handler and the old handler in a wrapper function that calls both of them.如果是这样,请将所需的处理程序和旧处理程序放在调用它们的包装函数中。

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 you don't want to override your own handler, check to see if you've set one:如果您不想覆盖自己的处理程序,请检查您是否已设置:

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

According to the documentation , is is possible that some superior process had already reassigned the handler from the default.根据文档,有可能某些高级进程已经从默认值中重新分配了处理程序。 If you don't want to override that, add None to the list of signals.如果您不想覆盖它,请将None添加到信号列表中。

The obvious wrapper for signal.signal(..., signal.SIG_IGN) would be a not in test. signal.signal(..., signal.SIG_IGN)的明显包装器将not in测试中。

added in response to comment添加以回应评论

Chaining signal handlers is not often done because signals are so granular.链接信号处理程序并不经常完成,因为信号非常细化。 If I really wanted to do this, I'd follow the model of atexit and register functions to be called by your handler.如果我真的想这样做,我会遵循atexit模型并注册由您的处理程序调用的函数。

Simply do the same as it would be done in C:只需像在 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)

The key idea here is that you save only the previous handler and raise it again when you finished your stuff.这里的关键思想是你只保存前一个处理程序,并在你完成你的东西后再次提出它。 In this way the signal handling is a single linked list OOB.通过这种方式,信号处理是一个单链表OOB。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM