pythonmultithreadingoop

Stopping a Python thread from class when an object gets deleted


I'm building a class which has a thread that does some work in the background. I want this thread to be deleted whenever the class is also deleted or goes out of scope. The code I'm using is equivalent to this:

from threading import Thread
from time import sleep
import sys

class Test:
    def __init__ (self):
        self._running_thread = False
        self._thread = None
    
    def _workFunc (self):
        while self._running_thread:
            print("Working...")
            sleep(1)
    
    def startThread (self):
        self._running_thread = True
        self._thread = Thread(target=self._workFunc)
        self._thread.start()
    
    def stopThread (self):
        self._running_thread = False
        self._thread.join()
    
    def __del__ (self):
        self.stopThread()

def main ():
    test = Test()
    test.startThread()
    sleep(3)
    print("Going out of scope!")

if __name__ == "__main__":
    sys.exit(main())

What I expect is that the thread is started, the working message gets printed three or four times, and then the test object goes out of scope, __del__ gets called, and the execution of the program resumes once the thread has finished. What happens instead is that the "Going out of scope!" message is printed after three seconds, but the thread keeps printing "working" indefinitely. What is happening, and how could I get the effect that I'm looking for?


Solution

  • You should use daemon threads because they are automatically terminated when the main program exits. This ensures that your program doesn't keep running indefinitely.

    When creating your thread, simply specify it as a daemon by passing daemon=true as an argument.

    like:

    def startThread(self):
        self._running_thread = True
        self._thread = Thread(target=self._workFunc, daemon=True)
        self._thread.start()
    

    Read more here