Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In python, is there a way to make threads that die when there is no longer a reference to them?

Sometimes I want a class that is continuously updated by a worker thread that it spawns when it is created. Basically like this:

class MyWidget:
    def __init__(self):
        self.blah = None
        self.thread = MyThread(self)
        self.thread.start()

    def update(self, blah):
        self.blah = blah

class MyThread(threading.Thread):
    def __init__(self, widget):
        self.widget = widget

    def run(self):
        while True:
            time.sleep(1)
            blah = poll()
            self.widget.update(blah)

I want a safe way to design this so that I'm sure the thread dies when the MyWidget is no longer needed. The problem with the above code is that the MyWidget will never die because it is being kept alive by the MyThread. I can fix that by giving the MyThread a weakref.ref to the MyWidget and breaking the loop when the reference dies but I have made the mistake of not doing this in the past.

What I'd really like is threads that get garbage collected along with everything else. ie. A thread that is killed when it's reference graph and the main thread's reference graph are disjoint. Would it be possible to write such a beast? Do they already exist?

like image 434
Shum Avatar asked Nov 12 '22 22:11

Shum


1 Answers

If you modify MyThread to provide a stop method:

class MyThread(threading.Thread):
    def __init__(self, widget):
        self.widget = widget
        self.is_running = False
        super(MyThread, self).__init__()

    def run(self):
        self.is_running = True
        while self.is_running:
            time.sleep(1)
            blah = poll()
            self.widget.update(blah)

    def stop(self):
        self.is_running = False

If at the point where you MyWidget instance is no longer needed you can call widget.thread.stop(), this will kill the thread and allow everything to be GC'd.

like image 114
Matthew Trevor Avatar answered Nov 15 '22 11:11

Matthew Trevor