代码之家  ›  专栏  ›  技术社区  ›  Justin Ethier

python-捕获所有信号

  •  22
  • Justin Ethier  · 技术社区  · 14 年前

    在Linux下的Python2.6中,我可以使用以下命令处理术语信号:

    import signal
    def handleSigTERM():
        shutdown()
    signal.signal(signal.SIGTERM, handleSigTERM)    
    

    除了一次设置一个处理程序外,是否有其他方法为进程接收的所有信号设置一个处理程序?

    6 回复  |  直到 6 年前
        1
  •  31
  •   Noufal Ibrahim    7 年前

    你可以在信号模块中循环信号并设置它们。

    for i in [x for x in dir(signal) if x.startswith("SIG")]:
      try:
        signum = getattr(signal,i)
        signal.signal(signum,sighandler)
      except (OSError, RuntimeError) as m: #OSError for Python3, RuntimeError for 2
        print ("Skipping {}".format(i))
    
        2
  •  13
  •   doctaphred    9 年前

    从Python3.5开始,信号常量是 defined as an enum ,实现更好的方法:

    import signal
    
    catchable_sigs = set(signal.Signals) - {signal.SIGKILL, signal.SIGSTOP}
    for sig in catchable_sigs:
        signal.signal(sig, print)  # Substitute handler of choice for `print`
    
        3
  •  10
  •   guettli    6 年前

    如果你想摆脱这种尝试,就忽略那些无法捕捉到的信号。

    #!/usr/bin/env python
    # https://stackoverflow.com/questions/2148888/python-trap-all-signals
    import os
    import sys
    import time
    import signal
    
    SIGNALS_TO_NAMES_DICT = dict((getattr(signal, n), n) \
        for n in dir(signal) if n.startswith('SIG') and '_' not in n )
    
    
    def receive_signal(signum, stack):
        if signum in [1,2,3,15]:
            print 'Caught signal %s (%s), exiting.' % (SIGNALS_TO_NAMES_DICT[signum], str(signum))
            sys.exit()
        else:
            print 'Caught signal %s (%s), ignoring.' % (SIGNALS_TO_NAMES_DICT[signum], str(signum))
    
    def main():
        uncatchable = ['SIG_DFL','SIGSTOP','SIGKILL']
        for i in [x for x in dir(signal) if x.startswith("SIG")]:
            if not i in uncatchable:
                signum = getattr(signal,i)
                signal.signal(signum,receive_signal)
        print('My PID: %s' % os.getpid())
        while True:
            time.sleep(1)
    main()
    
        4
  •  1
  •   Bryce Guinta    7 年前

    这里有一个2/3兼容的方法,没有其他方法那么多的陷阱:

    from itertools import count
    import signal
    
    def set_all_signal_signals(handler):
        """Set all signals to a particular handler."""
        for signalnum in count(1):
            try:
                signal.signal(signalnum, handler)
                print("set {}".format(signalnum))
            except (OSError, RuntimeError):
                # Invalid argument such as signals that can't be blocked
                pass
            except ValueError:
                # Signal out of range
                break
    

    自从 signalnum 只是一个数字,迭代1到超出范围,将信号设置为特定句柄。

        5
  •  1
  •   PeterB    6 年前

    适用于Windows 10和Python 3.7:

    import signal
    import time
    
    def sighandler(signal,frame):
        print("signal",sig,frame)
        return
    
    catchable_sigs = set(signal.Signals)
    for sig in catchable_sigs:
        try:
            signal.signal(sig, sighandler)
            print("Setting ",sig)
            print ("value {}".format(sig))
        except (ValueError, OSError, RuntimeError) as m:
            print("Skipping ",sig)
            print ("Value {}".format(sig))
    
    
    # press some keys or issue kill
    x = 0
    while x < 5:
        time.sleep(4)
        x += 1
    

    结果:

    Skipping  Signals.CTRL_C_EVENT
    Value 0
    Skipping  Signals.CTRL_BREAK_EVENT
    Value 1
    Setting  Signals.SIGINT
    value 2
    Setting  Signals.SIGILL
    value 4
    Setting  Signals.SIGFPE
    value 8
    Setting  Signals.SIGSEGV
    value 11
    Setting  Signals.SIGTERM
    value 15
    Setting  Signals.SIGBREAK
    value 21
    Setting  Signals.SIGABRT
    value 22
    
        6
  •  -1
  •   fixxxer    9 年前

    该代码在当前版本的python中不起作用。有许多以sig开头的变量具有相同的值。例如,sighup和sig_unblock都是1。我唯一能想到的办法就是 实际信号 只是我自己做的。

    from signal import *    
    signals = {
            SIGABRT: 'SIGABRT',
            SIGALRM: 'SIGALRM',
            SIGBUS: 'SIGBUS',
            SIGCHLD: 'SIGCHLD',
            SIGCONT: 'SIGCONT',
            SIGFPE: 'SIGFPE',
            SIGHUP: 'SIGHUP',
            SIGILL: 'SIGILL',
            SIGINT: 'SIGINT',
            SIGPIPE: 'SIGPIPE',
            SIGPOLL: 'SIGPOLL',
            SIGPROF: 'SIGPROF',
            SIGQUIT: 'SIGQUIT',
            SIGSEGV: 'SIGSEGV',
            SIGSYS: 'SIGSYS',
            SIGTERM: 'SIGTERM',
            SIGTRAP: 'SIGTRAP',
            SIGTSTP: 'SIGTSTP',
            SIGTTIN: 'SIGTTIN',
            SIGTTOU: 'SIGTTOU',
            SIGURG: 'SIGURG',
            SIGUSR1: 'SIGUSR1',
            SIGUSR2: 'SIGUSR2',
            SIGVTALRM: 'SIGVTALRM',
            SIGXCPU: 'SIGXCPU',
            SIGXFSZ: 'SIGXFSZ',
            }
    
    for num in signals:
        signal(num, h)
    
    推荐文章