Stop a thread on deletion

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Sjoerd Op 't Land

    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(thread ing.Thread):
    def __init__(self):
    self.passedOut = threading.Event ()
    threading.Threa d.__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_referrer s(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
  • Chris Mellon

    #2
    Re: Stop a thread on deletion

    On 8/8/07, Sjoerd Op 't Land <sjoerd@intercu e.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(thread ing.Thread):
    def __init__(self):
    self.passedOut = threading.Event ()
    threading.Threa d.__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_referrer s(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_referrer s 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(thread ing.Thread):
    def __init__(self):
    self.passedOut = threading.Event ()
    threading.Threa d.__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(obj ect):
    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()

    Comment

    • Sjoerd Op 't Land

      #3
      Re: Stop a thread on deletion

      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 <sjoerd@intercu e.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(thread ing.Thread):
      > def __init__(self):
      > self.passedOut = threading.Event ()
      > threading.Threa d.__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 )
      >>
      >Unfortunatel y, 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_referrer s(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_referrer s 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(thread ing.Thread):
      def __init__(self):
      self.passedOut = threading.Event ()
      threading.Threa d.__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(obj ect):
      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()

      Comment

      Working...