Threading.Condition problem

Piet van Oostrum piet at cs.uu.nl
Mon Jul 13 14:33:17 EDT 2009


>>>>> Gabriel Rossetti <gabriel.rossetti at arimaz.com> (GR) wrote:

>GR> Piet van Oostrum wrote:
...
>GR> I wrote a small example that listens for xmpp msgs in a thread. The main
>GR> program calls a function that blocks (using Condition.wait) until a msg
>GR> has been received and then returns the msg. When a msg arrives, it is
>GR> put in a variable in the thread's object, it then calls the notify()
>GR> attr on the Condition object. For some reason, this doesn't work, the
>GR> thread gets the msg, tries to notify the Condition object, fails because
>GR> the lock has not been acquired yet and blocks. I tried ignoring the
>GR> failure, thinking that since it has not been acquired yet then when it
>GR> is, it will get the msg right away and never call Condition.wait, thus
>GR> not causing any problems, but this does not work either. Does someone
>GR> know what I am doing wrong? I attached the code to this msg.
>>>> 
>>> 
>>> The code that puts the message in the variable should also acquire the
>>> lock:
>>> 
>>> 
>>> def onMessage(self, conn, msg):
>>> with self._cv:
>>> self.message = msg
>>> self._cv.notify()
>>> 

>GR> Thank you, that was the problem, I eventually found that
>>> A couple of remarks:
>>> 
>>> 1. I think the code is neater if all manipulation with the condition is
>>> done in the same class (actually in the same instance -- making this
>>> instance into a monitor).
>>> 

>GR> The reason I didn't do that is that I don' t want the Listener to sleep, I
>GR> maybe over simplified the example, I actually put them in a dictionary as
>GR> they come in, so in your example, if I have several threads waiting on msgs
>GR> it wouldn't work. I'm trying to make a webservice api thay will also be
>GR> turned into a java .jar for people that need java. Now that I think about
>GR> it, each session will have an instance of the object so msgs shouldn' t get
>GR> mixed up (one connection per user), so I could block in the thread. I'll
>GR> try your suggestion as I think it is cleaner.

Sleeping as you call it is better than busy waiting. You must have some
synchronisation to make it efficient.
If you put the messages in a dictionary access to the dictionary must be
protected. Having several threads waiting for the messages doesn't
prevent you from using proper synchronisation. Maybe you must use
notify_all instead of notify.
-- 
Piet van Oostrum <piet at cs.uu.nl>
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: piet at vanoostrum.org



More information about the Python-list mailing list