4

I cannot catch the INT signal in the main thread, please advise me how to fix the problem. I wish that the sleep method could be interrupted by CTRL+C, but it waits till the timer is ended..

import pygtk
pygtk.require('2.0')

import gtk
import time
import urllib2
import re
import signal
import sys

import __main__

from time import ctime, strftime, localtime
from threading import Thread

myThread = None

class MyThread(Thread):

    def __init__(self, filename):
        Thread.__init__(self)
        self.filename = filename;
        self.terminate = False

    def StopProcess(self):
        self.terminate = True

    def run(self):
        while self.terminate <> True:
            time.sleep(5)
            self.terminate = True

def SignalHandler(signum, frame):
    if (myThread <> None):
        myThread.StopProcess()
    sys.exit()

if __name__ == "__main__":

    signal.signal(signal.SIGINT, SignalHandler)

    myThread = MyThread("aaa")
    myThread.start()
1
  • The standard behavior is to catch SIGINT and translate it to KeyboardInterrupt exception. I'm curious if there is a reason that just trapping that exception instead is not adequate? Commented Jun 2, 2011 at 2:01

2 Answers 2

4

Signals are only delivered to one thread. Either only the first thread, or the first available thread depending on the operating system.

You'll have to implement you're own logic to shutdown the other threads, or make them daemon threads so they don't prevent the process from exiting.

Sign up to request clarification or add additional context in comments.

Comments

3

Believe it or not, this will work.

from Queue import Queue, Empty
def signal_safe_sleep(delay):
  q = Queue()
  try: q.get(True, delay)
  except Empty: pass

Alternatively, you can create some file descriptors using os.pipe() and then use select.select() on them within your signal_safe_sleep function. Both approaches will allow Python signal handlers to be called before signal_safe_sleep returns.

3 Comments

the same, I only changed the time.sleep function with your snippet and the script still does not react to ctrl+c and waits 5 secs..
Right, this will only work if your main thread is the one calling signal_safe_sleep, because the main thread is the one that gets the ^C. In your code, the main interpreter thread is already in its shutdown routine (joining all non-daemon threads) when the SIGTERM shows up. I'm not sure that your SignalHandler function is even being called in that case.
Yes, you were right, signal.pause() at the end of the main thread did it. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.