pyplot python linux signal-handling

pyplot - title plt python



Python-Atrapa todas las seƱales. (5)

A partir de Python 3.5, las constantes de señal se definen como una enumeración , lo que permite un enfoque más agradable:

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`

En Python 2.6 en Linux, puedo usar lo siguiente para manejar una señal TERM:

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

¿Hay alguna forma de configurar un controlador para todas las señales recibidas por el proceso, aparte de configurarlas una a la vez?


Aquí hay una forma compatible con 2/3 que no tiene tantos escollos como los demás:

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

Dado que signalnum es solo un número, repita de 1 a fuera de rango y establezca la señal en un identificador particular.


Ese código no funcionará en la versión actual de python. Hay muchas variables que comienzan con SIG con el mismo valor. Por ejemplo, SIGHUP y SIG_UNBLOCK son ambos 1. La única forma en la que se me ocurrió obtener una lista de señales reales fue hacerlo yo mismo.

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)


Si desea deshacerse del intento, simplemente ignore las señales que no puedan ser detectadas.

#!/usr/bin/env python # https://.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()


Usted podría simplemente pasar por las señales en el módulo de señal y configurarlas.

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))