0

I wrote a test application shown below to illustrate my problem with capturing a keyboard interrupt. The try catch block running in the main thread of execution does not even get an interrupt. Pressing and holding down Control-C in the terminal shows that a bunch of ^C on the screen, but the program keeps running. It does not even print out that it received the stop command.

I have read numerous SO posts and non-SO posts on this issue including:

  • This post, which solved a problem that looks rather similar to this problem by introducing daemons (which I have done)
  • This post, whom gave up and "solved" the problem using a busy loop
  • This article, which apparently has not encountered problem I have
  • And this post, which I used for an attempt to install the interrupt handler manually... Still, nothing.

I also changed the a.finish.wait() to a.join(); same issue. All the articles I have read either apparently do not have this issue or give up and solve it with a busy loop. I would greatly appreciate holding off on creating a busy loop unless absolutely necessary.

import time
import threading


class A(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.setDaemon(True)
        self.running = True
        self.finish = threading.Event()

    def stop(self):
        print('STOP!')
        self.running = False

    def run(self):
        while self.running:
            print('I am sleeping. Don\'t bother me.')
            time.sleep(1)
        self.finish.set()


a = A()
a.start()
try:
    a.finish.wait()
except KeyboardInterrupt:
    print('STOP A!')
    a.stop()
a.finish.wait()
Community
  • 1
  • 1
jakebird451
  • 2,288
  • 4
  • 30
  • 45
  • Did you see [this question](http://stackoverflow.com/questions/2829329/catch-a-threads-exception-in-the-caller-thread-in-python)? – BrenBarn Jan 16 '15 at 05:13
  • It's worth noting that this is only an issue in python2. In python3 `wait` was changed a lot and can be interrupted. – Ryne Everett Jan 16 '15 at 06:02
  • @RyneEverett That is a good point. It works fine in Python3, but not in Python2. Is the issue with both `join` and `wait`? Is there a clean way to fix this? – jakebird451 Jan 16 '15 at 06:10
  • 1
    I don't know, but I wouldn't feel too bad about using a loop. But don't use a busy loop -- a `sleep(0.1)` is enough to give up the GIL, cheap on CPU, and an undetectable delay to the user. – Ryne Everett Jan 16 '15 at 06:24

0 Answers0