import signal
import sys
import time
def sigint_handler(signal, frame):
print "signal"
sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)
while 1:
try:
print "text"
time.sleep(2)
except KeyboardInterrupt:
print "keybi"
exit(0)
except:
print "except"
continue
When I press Ctrl-C I see "signal" and "except" and the program doesn't exit.
Why doesn't the program exit, while it apparently reaches sys.exit(0)
?
Why doesn't the program flow reach the KeyboardInterrupt
section?
What is the concise way to make Ctrl-C work and handle each except:
case separately in different places without exiting?
A Signal Handler is a user defined function, where Python signals can be handled. If we take the signal SIGINT (Interrupt Signal), the default behavior would be to stop the current running program. We can, however, assign a signal handler to detect this signal and do our custom processing instead!
In Python, exceptions can be handled using a try statement. The critical operation which can raise an exception is placed inside the try clause. The code that handles the exceptions is written in the except clause. We can thus choose what operations to perform once we have caught the exception.
Exception handling allows you to separate error-handling code from normal code. An exception is a Python object which represents an error. As with code comments, exceptions helps you to remind yourself of what the program expects. It clarifies the code and enhances readability.
Python provides the Signal library allowing developers to catch Unix signals and set handlers for asynchronous events. For example, the 'SIGTERM' (Terminate) signal is received when issuing a 'kill' command for a given Unix process.
The program doesn't exit because sys.exit
works by throwing a SystemExit
exception, and your blanket except
caught it.
The except KeyboardInterrupt
doesn't fire because the SIGINT
handler you installed overrides the default SIGINT
handler, and the default SIGINT
handler is responsible for raising a KeyboardInterrupt
when you hit Ctrl-C.
As for your third question, it's unclear what you're asking.
@user2357112 answered your first two questions, as to your third, you can create your own exception in the signal handler. In this example we raise MyError
in the event of a SIGINT.
import signal
import time
class MyError(Exception):
pass
def handler(sig, frame):
raise MyError('Received signal ' + str(sig) +
' on line ' + str(frame.f_lineno) +
' in ' + frame.f_code.co_filename)
signal.signal(signal.SIGINT, handler)
try:
while 1:
time.sleep(1) # Hit <CTRL>+C here
except KeyboardInterrupt:
print('Keyboard interrupt caught')
except MyError as err:
print("Hiccup:",err)
# do stuff
print('Clean exit')
If you comment out the call to signal.signal()
then you will get a KeyboardInterrupt, as described.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With