Confusion with weakref, __del__ and threading

Rhamphoryncus rhamph at gmail.com
Wed Jun 11 20:01:47 CEST 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