472,103 Members | 1,063 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,103 software developers and data experts.

Stop a thread on deletion

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.

Thanks in advance for any suggestion,
Sjoerd Op 't Land
Aug 8 '07 #1
2 1739
On 8/8/07, Sjoerd Op 't Land <sj****@intercue.nlwrote:
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()
Aug 8 '07 #2
Dear Cris,

Thanks a lot. This works! (What you didn't know, there was already such
a 'proxy' object in the design, so it isn't the hack it looks ;).)

Thanks again,
Sjoerd Op 't Land

Chris Mellon schreef:
On 8/8/07, Sjoerd Op 't Land <sj****@intercue.nlwrote:
>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()
Aug 8 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

9 posts views Thread by Harald Armin Massa | last post: by
1 post views Thread by Peter Steele | last post: by
3 posts views Thread by Niyazi | last post: by
8 posts views Thread by Tim Bücker | last post: by
26 posts views Thread by Ricardo | last post: by
3 posts views Thread by Saizan | last post: by
9 posts views Thread by Jon Slaughter | last post: by
reply views Thread by =?Utf-8?B?anAybXNmdA==?= | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.