KeyboardInterrupt and threading
Ivan Nestlerode
q2n8byu02 at sneakemail.com
Tue Jan 6 21:44:07 EST 2004
Michael Hudson <mwh at python.net> wrote in message news:<m3fzeu73k3.fsf at pc150.maths.bris.ac.uk>...
> On debian, the signal module certainly should be available, and the
> KeyboardInterrupt exception should go to the main thread. Or at
> least, that's what I thought. You're definitely seeing it being
> delivered to an arbitrary thread?
>
> Cheers,
> mwh
After a closer look, I am not seeing KeyboardInterrupt being delivered
to non-main threads. What I am seeing is that Ctrl-C does not work at
all when non-main threads are CPU intensive. I had previously jumped
to the conclusion that because Ctrl-C didn't work and because the
non-main thread was sloppy ("except:"), that Ctrl-C wasn't working
because KeyboardInterrupt was going to the sub-thread. That was an
incorrect conclusion.
So I guess the entire problem can be restated as:
How do I make Ctrl-C work properly when the non-main thread is busier
than the main thread?
The short program at the end of this post demonstrates the problem
with Ctrl-C and busy non-main threads. The idea behind this script is
that the main thread launches a busy sub-thread. Ctrl-C is supposed to
be caught in the main thread, stopping both threads, and ending the
program (with some printouts). As written, the program does not
respond to Ctrl-C even if I hold it down continuously. If you
uncomment the print statement in the main thread, all of the sudden it
starts to work. Why?
I think it has something to do with the main thread needing some
larger amount of CPU to detect the signal and the KeyboardInterrupt. I
think this is a bug though (I shouldn't have to put hacks into the
main thread to get this to work).
Any thoughts?
Thanks,
-Ivan
#!/usr/bin/python
from threading import Event, Thread
from time import sleep
class CpuHogThread(Thread):
def __init__(self):
Thread.__init__(self)
self.counter = 0
self.stopEvent = Event()
def join(self):
self.stopEvent.set()
Thread.join(self)
def run(self):
try:
while not self.stopEvent.isSet():
self.counter += 1
except KeyboardInterrupt:
print 'CPU hog subthread caught KeyboardInterrupt'
if __name__ == '__main__':
t = CpuHogThread()
t.start()
print 'CPU hog subthread spawned'
try:
while True:
sleep(2)
# without the next print, Ctrl-C is completely ignored
#print 'still sleeping'
except KeyboardInterrupt:
print 'main thread caught KeyboardInterrupt'
t.join()
print 'CPU hog subthread joined at counter %d' % t.counter
More information about the Python-list
mailing list