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