Given the following code (running under Linux)...
import threading
import time
def donothing(quit):
while True:
if quit.wait(1):
break
print 'quitting'
quit = threading.Event()
try:
t = threading.Thread(target=donothing, args=(quit,))
t.start()
t.join()
except KeyboardInterrupt:
print 'interrupt!'
quit.set()
Type ^C
while the program is running will not generate a KeyboardInterrupt
:
python example.py
^C^C^C^C^C^C^C^C^C
Adding a timeout of any value to t.join()
changes this behavior. That is, if I have instead:
t.join(86400)
Then I see (without needing to wait 86400 seconds):
$ python example.py
^Cinterrupt!
quitting
What is going on here? I assume that in the first case the join
operation locks the GIL and prevents any signal handlers from running, but why does adding any timeout change this behavior?
I've spent a little time poking through the code, and while I'm getting lost somewhere in Modules/_threadmodule.c
it looks as if the same code path is followed regardless of whether or not a timeout was specified.