1

I did a little search and found out there is no way to kill a thread in python, but how would one solve a problem like me ?

I have a function that sets X to True for one hour and after that it sets it back to False.

sometimes the program finishes less than the needed hour, but the thread is still running and make garbage in memory.

    def enableX():
        self.x=True
        sleep(3600)
        self.x=False
    def function1():
        self.enableXThread=Thread(target=self.enableX) 
        self.enableXThread.start()

any idea ? how I can kill enbableXThread when the program terminates no matter if the thread is done or not ?

Medya Gh
  • 4,563
  • 5
  • 23
  • 35
  • Have it sleep in intervals and periodically check if the other process is finished (set some sort of class variable and have it check an object's variable that will indicate when finished). – Dan Jul 11 '13 at 15:15

2 Answers2

1

how I can kill enbableXThread when the program terminates

If the thread does not have any cleanup to do, make it a daemon thread by setting enableXThread.daemon to True. This must be done before starting the thread:

self.enableXThread = Thread(target=self.enableX) 
self.enableXThread.daemon = True
self.enableXThread.start()

Otherwise, use an exit flag (a global variable that the threads check to see whether they should exit) or an Event handler.

You might also considering using a signal for this, as this may be simpler than threading; you can simply set an alarm for an hour and have the handler reset the variable. If your process ends before the alarm goes off, nothing happens. Note that this isn't available on Windows.

import signal

X = False

def handle_alarm(signum, frame):
    global X
    X = False

signal.signal(signal.SIGALRM, handle_alarm)

def set_X_true_then_false_later(secs=3600):
    global X
    X = True
    signal.alarm(secs)
kindall
  • 178,883
  • 35
  • 278
  • 309
  • if I set the daemon True will it be killed when the program terminates? – Medya Gh Jul 11 '13 at 16:31
  • Yes, the interpreter terminates when only daemon threads are left. – kindall Jul 11 '13 at 17:02
  • doesnt that mean, when the thread finishes, it will also kill the whole program? I want the whole program to continue if the thread finishes, but I only want the thread to be killed if the program finishes sooner – Medya Gh Jul 11 '13 at 17:17
  • Your main thread is not a daemon thread, so the interpreter won't terminate until it finishes. – kindall Jul 11 '13 at 17:31
  • I've also added an alternate way to do this using signals. – kindall Jul 11 '13 at 18:16
0

It looks like your problem has already been solved using kindall's suggestions, but if you ever are interested in being able to terminate a thread from another one, the following might be of interest to you.


If you do not mind your code running about ten times slower, you can use the Thread2 class implemented below. An example follows that shows how calling the new stop method should kill the thread on the next bytecode instruction.

import threading
import sys

class StopThread(StopIteration): pass

threading.SystemExit = SystemExit, StopThread

class Thread2(threading.Thread):

    def stop(self):
        self.__stop = True

    def _bootstrap(self):
        if threading._trace_hook is not None:
            raise ValueError('Cannot run thread with tracing!')
        self.__stop = False
        sys.settrace(self.__trace)
        super()._bootstrap()

    def __trace(self, frame, event, arg):
        if self.__stop:
            raise StopThread()
        return self.__trace


class Thread3(threading.Thread):

    def _bootstrap(self, stop_thread=False):
        def stop():
            nonlocal stop_thread
            stop_thread = True
        self.stop = stop

        def tracer(*_):
            if stop_thread:
                raise StopThread()
            return tracer
        sys.settrace(tracer)
        super()._bootstrap()

################################################################################

import time

def main():
    test = Thread2(target=printer)
    test.start()
    time.sleep(1)
    test.stop()
    test.join()

def printer():
    while True:
        print(time.time() % 1)
        time.sleep(0.1)

if __name__ == '__main__':
    main()

The Thread3 class appears to run code approximately 33% faster than the Thread2 class.

Noctis Skytower
  • 21,433
  • 16
  • 79
  • 117