Python - Trap All Signals

Python - Trap all signals

You could just loop through the signals in the signal module and set them up.

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

How do I capture SIGINT in Python?

Register your handler with signal.signal like this:

#!/usr/bin/env python
import signal
import sys

def signal_handler(sig, frame):
print('You pressed Ctrl+C!')
sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)
print('Press Ctrl+C')
signal.pause()

Code adapted from here.

More documentation on signal can be found here.
 

Catching signals other than SIGINT in Python

POSIX specifies exactly two user defined signals:

SIGUSR1 = 30
SIGUSR2 = 31

These two signals aren't triggered by any action, meaning you can explicitly define handlers for these and raise these signals for your purpose.

import signal

def handler(signum):
if signum == signal.SIGUSR1:
print('user defined interrupt!')

signal.signal(signal.SIGUSR1, handler)

These signals have been provided explicitly for the user's purpose, so it would be a good idea to raise and handle these signals in your application.


To explicitly raise this signal with code, you would have to use:

import os
os.kill(os.getpid(), signal.SIGUSR1)

Where os.getpid() returns the process ID of the current process. Replace this with the ID of the process you wish to kill (if it isn't the current one).

Also, I should mention that SIGUSR1/2 are not supported in Windows. The documentation mentions that besides SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, or SIGTERM, no other signal can be raised. A ValueError will be raised in any other case.

Why Python subprocesses won't properly capture signals?

This is a race condition.

You are forking and immediately sending the signal, so it's a race for the child process to ignore it before it gets killed.

Furthermore, your parent script has a race condition in checking whether the script has died. You signal the script and immediately check if it's dead, so it's a race for the child to die before the check happens.

If you add a time.sleep(1) before sending the signal, you'll make sure the child wins the race and therefore you get the behavior you expect.

python: catch SIGINT in process reading data from a socket

Looks like your internal loop is blocking progBreak check, this code is working for me:

import signal

progBreak = False

def newBreakHandler(signum, frame):
global progBreak
progBreak = True


def runMain():
global progBreak

signal.signal(signal.SIGINT, newBreakHandler)


while not progBreak:
while not progBreak and client.poll():
command = client.recv_bytes()

print "Exiting..."

runMain()

How to process SIGTERM signal gracefully?

A class based clean to use solution:

import signal
import time

class GracefulKiller:
kill_now = False
def __init__(self):
signal.signal(signal.SIGINT, self.exit_gracefully)
signal.signal(signal.SIGTERM, self.exit_gracefully)

def exit_gracefully(self, *args):
self.kill_now = True

if __name__ == '__main__':
killer = GracefulKiller()
while not killer.kill_now:
time.sleep(1)
print("doing something in a loop ...")

print("End of the program. I was killed gracefully :)")


Related Topics



Leave a reply



Submit