473,406 Members | 2,619 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

weakref and thread safety (in python 2.1)

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

Jul 18 '05 #1
1 2606
"Ames Andreas (MPA/DF)" <An**********@tenovis.com> wrote in
news:ma**********************************@python.o rg:
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.
That's because when the only way to use a weak reference is to convert it
into a strong reference. So when you call:

myweakref.put(item)

you create a strong reference that exists until the put method returns (and
in fact some more references are created such as the self parameter inside
the put method).

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.


No, this isn't thread safe. You have again got a strong reference while
calling the method, so the only place the weak reference could be destroyed
is outside the method call, and by that time thread2 could have blocked on
the queue again.

However, if you repeatedly try to pull data out of the queue, you should
eventually get somewhere.

qw = weakref.ref(q) # a second weak reference (this time within
# thread1)
del q
while qw:
qw().get_nowait()

There is still a problem though as your code is free-running: if the queue
gets empty before it is released you may use a lot of CPU before it
eventually gets freed. Also you are depending on the memory behaviour of C
Python, if Zope ever gets ported to Jython you will probably find that weak
references don't go away until the garbage collector kicks in.

A much better way to do this would be to make the termination explicit.

e.g. (untested code)

class MyQueue(Queue):
def __init__(self, maxsize=0):
Queue.__init__(self, maxsize)
self.terminated = False

thread2, with queue a normal reference to a MyQueue instance:

while 1:
item = produce()
queue.put(item)
if queue.terminated:
break # Stop processing queue

thread1 can then terminate the queue with:

queue.terminated = True
queue.get_nowait() # Ensure any blocked put completes.

No weak references needed.

--
Duncan Booth du****@rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
Jul 18 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: MetalOne | last post by:
Are atomic operations thread safe in Python? Can immutable objects, such as, strings, be created on one thread and then accessed by another thread, without using locks? Such operations are not...
1
by: Mathias Mamsch | last post by:
Hi, I have some confusion concerning the weakref module. I am trying to save a weak reference to a bound member function of a class instance for using it as a callback function. But I always...
20
by: Ken Godee | last post by:
module1 calls a function in module2 module2 starts a thread that calls a function in module3 and then returns to module1 thread finishes and I need the return value from the thread to use in...
1
by: Casper | last post by:
i make a multi thread C/C++ program emded python, each thread running a python sub-interpreter, to make it safety i make code as following between acquire/release the globle interpreter lock:...
8
by: Torsten Mohr | last post by:
Hi, i write an extension module in C at the moment. This module does some work on some own data types that consist of some values. The functions that can change the data are written in C. ...
4
by: Jonathan Burd | last post by:
Greetings everyone, Here is a random string generator I wrote for an application and I'm wondering about the thread-safety of this function. I was told using static and global variables cause...
2
by: Robin Haswell | last post by:
Hey guys I've been reading http://www.python.org/peps/pep-0249.html and I don't quite get what level of thread safety I need for my DB connections. If I call db = FOOdb::connect() at the start...
6
by: fniles | last post by:
I am using VB.NET 2003 and a socket control to receive and sending data to clients. As I receive data in 1 thread, I put it into an arraylist, and then I remove the data from arraylist and send it...
6
by: George Sakkis | last post by:
I'm baffled with a situation that involves: 1) an instance of some class that defines __del__, 2) a thread which is created, started and referenced by that instance, and 3) a weakref proxy to the...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.