Short form question:
How do I get a keyboard interrupt to stop a Python thread?
Details:
Consider the following simple program:
import time
def test():
while(True):
print(time.asctime(), flush=True)
time.sleep(3)
if __name__ == '__main__':
test()
When I run it in a cmd window and type ^C, it terminates the program as expected:
>py test.py
Tue Jul 18 08:34:33 2023
Tue Jul 18 08:34:36 2023
Traceback (most recent call last):
File "C:\Users\r\Projects\Pro1\git\pro1-pubsub\test.py", line 22, in <module>
test()
File "C:\Users\r\Projects\Pro1\git\pro1-pubsub\test.py", line 13, in test
time.sleep(3)
KeyboardInterrupt
^C
But if the code is running in a thread, ^C has no effect -- it just keeps running and the only way I've found to stop it is to open the Task Manager and terminate the Python process:
import threading
import time
def test():
threading.Thread(target=listen_thread).start()
def listen_thread():
print("listen_thread", flush=True)
while(True):
print(time.asctime(), flush=True)
time.sleep(3)
if __name__ == '__main__':
test()
I also tried setting a signal handler like this, but signal_handler()
never gets called:
import signal
import sys
import threading
import time
runnable = True;
def test():
threading.Thread(target=listen_thread).start()
def listen_thread():
print("listen_thread starting", flush=True)
while(runnable):
print(time.asctime(), flush=True)
time.sleep(3)
print("listen_thread stopping", flush=True)
def signal_handler(signal, frame):
global runnable
print("setting runnable to False", flush=True)
runnable = False
if __name__ == '__main__':
signal.signal(signal.SIGINT, signal_handler)
test()
The question (redux):
How do I get a keyboard interrupt to stop the thread?