weakref and thread safety (in python 2.1)

Ames Andreas (MPA/DF) Andreas.Ames at tenovis.com
Tue Jul 22 07:10:21 EDT 2003


Hi all,

I'm using python 2.1 and can't easily upgrade (Zope).  I'm using the 
Queue module to synchronize/communicate between two threads and
weakref.proxy objects to avoid cycles.  Scenario:

thread1:

- is the sole consumer (non-blocking get)
- holds the reference to the queue

thread2:

- is the sole producer (blocking put)
- holds a weak reference to the queue

I've noted that, when thread2 incidentally blocks on the queue
(because it's full), while thread1 deletes the queue, the weak
reference isn't deleted and thread2 keeps blocking forever.

I came up with the following destruction scheme for the queue (within
thread1; q is the 'strong' ref to the queue), which *seems* to solve
my problem (as of some preliminary tests):

qw = weakref.proxy(q)   # a second weak reference (this time within
                        # thread1) 
del q
try:
        qw.get_nowait() # if thread2 blocks on the (weakrefed) queue,
                        # qw still exists here;  the get_nowait() call
                        # wakes thread2 up.  I *hope* that its
                        # weakreference will be destroyed when it can
                        # block again in its next call to put()
                        # (leading to a weakref.ReferenceError)
except:
        pass

Is this thread-safe?  I don't know enough about the implementation of
the weakref module to decide if it is guaranteed that thread2's weak
reference to the queue will be destroied *before* thread2 can call
'put()' (or rather before thread2 can block) for the next time.  Can
someone more knowledgeable help me out please?


TIA,

andreas





More information about the Python-list mailing list