Roman Prykhodchenko
Roman Prykhodchenko

Reputation: 13315

How to interrupt python multithreaded app?

I'm trying to run the following code (it i simplified a bit):

def RunTests(self):
        from threading import Thread
        import signal

        global keep_running
        keep_running = True
        signal.signal( signal.SIGINT, stop_running )

        for i in range(0, NumThreads):
            thread = Thread(target = foo)
            self._threads.append(thread)
            thread.start()

# wait for all threads to finish
        for t in self._threads:
            t.join()

def stop_running(signl, frme):  
    global keep_testing
    keep_testing = False 
    print "Interrupted by the Master. Good by!"
    return 0 

def foo(self):

    global keep_testing

    while keep_testing:
        DO_SOME_WORK();

I expect that the user presses Ctrl+C the program will print the good by message and interrupt. However it doesn't work. Where is the problem?

Thanks

Upvotes: 3

Views: 672

Answers (2)

Mew
Mew

Reputation: 1049

From the threading docs:

A thread can be flagged as a “daemon thread”. The significance of this flag is that the entire Python program exits when only daemon threads are left. The initial value is inherited from the creating thread. The flag can be set through the daemon property.

You could try setting thread.daemon = True before calling start() and see if that solves your problem.

Upvotes: 0

Rakis
Rakis

Reputation: 7874

Unlike regular processes, Python doesn't appear to handle signals in a truly asynchronous manner. The 'join()' call is somehow blocking the main thread in a manner that prevents it from responding to the signal. I'm a bit surprised by this since I don't see anything in the documentation indicating that this can/should happen. The solution, however, is simple. In your main thread, add the following loop prior to calling 'join()' on the threads:

while keep_testing:
    signal.pause()

Upvotes: 3

Related Questions