KeyboardInterrupt and threading

Ivan Nestlerode q2n8byu02 at sneakemail.com
Wed Jan 7 04:09:19 CET 2004


"Paul McGuire" <ptmcg at austin.rr.com> wrote in message news:<XhEJb.40848$DC4.32293 at fe2.texas.rr.com>...
> Is the signal module not available to you?
> <snip>
> Assuming you have access to the signal module:
> 1. Create a boolean that you can periodically test for in your thread code,
> to see if you should keep processing.  This may be a global singleton, a
> global boolean, or something, but it needs to be visible to both the main
> thread and the threaded code.  You probably have some compute intensive
> loops such as:
>     while( prime_factors < 1e15 ):
> or
>     while( optimization != converged ):
> or even just
>     while( True ):
> 
> Change these to reference the "keep processing" flag.
>     while( keep_processing and prime_factors < 1e15 ):
> or
>     while( keep_processing and optimization != converged ):
> or even just
>     while( keep_processing ):  # no need to 'and' with True
> 
> 2. Create a signal handler to trap for SIGINT. In the signal handler, set
> the "keep-processing" bit to False:
> 
> <snip>
> 
> Now your main thread will get the ^C interrupt and clear the
> "keep_processing" flag, which will eventually get picked up by your worker
> thread the next time it tests for it.
> 
> HTH,
> -- Paul

I do have the signal module (Python 2.3.2 on Linux), but
unfortunately, even registering a signal handler doesn't fix the
problem where busy non-main threads prevent Ctrl-C from working.

Here is another code snippet using a signal handler (this code is very
similar to the code from my second post). If the main thread's loop
has the print statement, everything works fine. If it is commented out
(as written here), Ctrl-C is ignored completely and the program just
keeps running. Why won't this work? Is this a bug?

Thanks,
-Ivan

#!/usr/bin/python

from signal import signal, SIGINT
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'

def handler(signal, frme):
    stopEvent.set()
    print 'main thread SIGINT handler'
    t.join()
    print 'CPU hog subthread joined at counter %d' % t.counter
    return 0

if __name__ == '__main__':
    stopEvent = Event()
    signal(SIGINT, handler)
    t = CpuHogThread()
    t.start()

    print 'CPU hog subthread spawned'
    try:
        while not stopEvent.isSet():
            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