Confusion with weakref, __del__ and threading
Rhamphoryncus
rhamph at gmail.com
Wed Jun 11 14:01:47 EDT 2008
On Jun 11, 10:43 am, George Sakkis <george.sak... at gmail.com> wrote:
> On Jun 11, 1:40 am, Rhamphoryncus <rha... at gmail.com> wrote:
> > The trick here is that calling proxy.sleep(0.01) first gets a strong
> > reference to the Mystery instance, then holds that strong reference
> > until it returns.
>
> Ah, that was the missing part; I thought that anything accessed
> through a proxy didn't create a strong reference. The good thing is
> that it seems you can get a proxy to a bounded method and then call it
> without creating a strong reference to 'self':
That's not right. Of course a bound method has a strong reference to
self, otherwise you'd never be able to call it. There must be
something else going on here. Try using sys.setcheckinterval(1) to
make threads switch more often.
>
> num_main = num_other = 0
> main_thread = threading.currentThread()
>
> class MysterySolved(object):
>
> def __init__(self):
> sleep = weakref.proxy(self.sleep)
> self._thread = threading.Thread(target=target, args=(sleep,))
> self._thread.start()
>
> def __del__(self):
> global num_main, num_other
> if threading.currentThread() is main_thread:
> num_main += 1
> else:
> num_other += 1
>
> def sleep(self, t):
> time.sleep(t)
>
> def target(sleep):
> try: sleep(0.01)
> except weakref.ReferenceError: pass
>
> if __name__ == '__main__':
> for i in xrange(1000):
> MysterySolved()
> time.sleep(.1)
> print '%d __del__ from main thread' % num_main
> print '%d __del__ from other threads' % num_other
>
> ==========================================
> Output:
> 1000 __del__ from main thread
> 0 __del__ from other threads
>
> Thanks a lot, I learned something new :)
>
> George
More information about the Python-list
mailing list