no return value for threading.Condition.wait(timeout)?
Gabriel Rossetti
gabriel.rossetti at arimaz.com
Fri Jul 17 02:12:38 EDT 2009
Maxim Khitrov wrote:
> On Thu, Jul 16, 2009 at 5:00 PM, Carl Banks<pavlovevidence at gmail.com> wrote:
>
>> On Jul 16, 8:12 am, Gabriel Rossetti <gabriel.rosse... at arimaz.com>
>> wrote:
>>
>>> Hello everyone,
>>>
>>> I am using threading.Condition.wait(timeout) and was surprised to see
>>> that there is no return value nor an exception when wait() is used w/ a
>>> timeout. How am I supposed to know if it was notified or if it timed out?
>>>
>> That's a good question. Condition.wait seems to violate an invariant
>> if it can return without having acquired the underlying lock. And if
>> it does the least it could do is to return a status so you know if you
>> have to skeddadle.
>>
>> Workaround is to use the _is_owned() method of Condition to see if you
>> are the owner of the condition, but this method is undocumented.
>>
>> cond = Condition()
>> ...
>> cond.acquire()
>> while not ok_to_proceed():
>> cond.wait()
>> if not cond._is_owned():
>> # must've timed out
>> raise TimeOutException
>> operate()
>> cond.release()
>>
>
> You will always be the owner of the condition whether it times out or
> your thread is notified. This doesn't solve the problem. As an aside,
> the implementation of wait() is rather poor in any case; the sleep
> function should not be used for the purpose of waiting for an event.
>
> Depending on what platform you are using, I can offer two solutions.
> The simplest one is to subclass Condition and override the wait
> method. Just copy the code as it is, but modify the end of the
> function to look like this:
>
> if not gotit:
> if __debug__:
> self._note("%s.wait(%s): timed out", self, timeout)
> try:
> self.__waiters.remove(waiter)
> except ValueError:
> pass
> return False
> else:
> if __debug__:
> self._note("%s.wait(%s): got it", self, timeout)
> return True
>
> The two return statements will tell you whether you timed out ("if not
> gotit" condition), or were notified ("else").
>
> The better way to solve this and the other problem that I mentioned is
> to use native OS events. This is what I had to do for a recent
> project. I used pywin32 extension to completely rewrite Event,
> Condition, and Timer classes to use a true event-based approach. In
> the process of the rewrite I also modified some functionality, such as
> returning True of False from wait().
>
> Unfortunately, I'm not able to post this code right now, though I can
> try and get permission to do so a bit later. If you are writing
> software for Windows, then simply take a look at win32event module.
> CreateEvent, SetEvent, ResetEvent, WaitForSingleObject are all the
> Windows functions that you need to reimplement threading.Event. Using
> the new event class you can implement a proper Condition.wait() method
> (hint: use new events rather than locks to wait for notification).
>
> If you are on Linux or BSD, I can't help you. I'm sure that there is
> some equivalent functionality that you may be able to access using
> ctypes. Exactly how to do it, however, is not something that I can
> help you with right now.
>
> - Max
>
Thank you, I will try that. I am coding for Linux, Mac & Windows (and
any POSIX platform, but right now I support only those three).
Gabriel
More information about the Python-list
mailing list