Reputation: 3758
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?
Upvotes: 8
Views: 14339
Reputation: 44354
@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.
Upvotes: 3
Reputation: 280465
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.
Upvotes: 11