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