Stop a thread on deletion

Chris Mellon arkanes at gmail.com
Wed Aug 8 11:10:15 EDT 2007


On 8/8/07, Sjoerd Op 't Land <sjoerd at intercue.nl> wrote:
> Hello all,
>
> I'm using threading for generating video content. The trouble is how to
> kill the thread, because there are multiple (simultaneous) owners of a
> thread. Ideally, a flag would be set when the reference count of the
> thread becomes zero, causing the run() loop to quit. Example:
>
> import threading
> import time
> import gc
>
> class myThread(threading.Thread):
>    def __init__(self):
>      self.passedOut = threading.Event()
>      threading.Thread.__init__(self)
>    def __del__(self):
>      self.passedOut.set()
>    def run(self):
>      i = 0
>      while not self.passedOut.isSet():
>        i += 1
>        print "Hi %d" % i
>        time.sleep(0.25)
>
>
> a = myThread()
> a.start()
> time.sleep(2.5)
> a = None
> time.sleep(2.5)
>
> Unfortunately, this doesn't work. When I remove the while-loop, __del__
> is called, actually. Appearantly there is still some reference to the
> thread while it is running.
>
> I tried gc.get_referrers(self), but it seems to need some parsing. I'm
> not sure how to implement that and I'm not sure whether it will work
> always or not.
>

gc.get_referrers returns a list of object instances that hold a
reference to the object. The important one in this case is, of course,
the thread itself. The thread holds a reference to the run method
which (of course) requires a reference to the object. In other words,
a running thread cannot be refcounted to zero. You are going to need a
better method of handling your resources.

Perhaps instead of holding a reference to the thread, they could hold
a reference to a proxy object:

import threading
import time
import gc
import pprint

class myThread(threading.Thread):
    def __init__(self):
        self.passedOut = threading.Event()
        threading.Thread.__init__(self)
    def run(self):
        i = 0
        while not self.passedOut.isSet():
          i += 1
          print "Hi %d" % i
          time.sleep(1)
        print "stopped"


class ThreadProxy(object):
    def __init__(self, proxy_for):
        self.proxy_for = proxy_for
    def __del__(self):
        self.proxy_for.passedOut.set()
    def start(self):
        self.proxy_for.start()



More information about the Python-list mailing list