I have some program logic that works as follows:
for i in range(10**6):
foo(i)
print("foo executed with parameter", i)
bar(i)
print("bar executed with parameter", i)
The problem arises when I want to interrupt the loop with Ctrl C to raise a KeyboardInterrupt
.
I make sure that the function bar(i)
always runs after the function foo(i)
; i.e. the loop cannot be interrupted between the two function calls (or, if it is, I want to complete the loop before exiting). If the interrupt is received while one of the functions is being executed, I want both to finish before exiting.
How is this achievable (with a try...except
statement or otherwise) in Python 3?
CodePudding user response:
Thank you to Omer Ben Haim for providing an answer in the comments.
Indeed, the SIGINT signal can be captured using the signal
module. Here is some proof-of-concept code that demonstrates this:
import signal
import time
stop = False
def handler(sig, frame):
global stop
stop = True
signal.signal(signal.SIGINT, handler)
############
i = 0
while i<10**6 and not stop:
print("Part 1:", i)
time.sleep(0.5)
print("Part 2:", i)
time.sleep(0.5)
i = 1
CodePudding user response:
This could be done rather easily using a flag.
When a KeyboardInterrupt is raised(E.g. Ctrl c is pressed), you capture it and set the quit_loop flag to True.
When we finish what we need to do, we check if we need to quit the loop and if we do then we break.
If you want to fully exit the program you can replace break
with exit()
.
quit_loop = False
for i in range(10):
try:
foo()
except KeyboardInterrupt:
quit_loop = True
bar()
if quit_loop:
break