The Python Oracle

How to know if threading.Condition.wait(timeout) has timed out or has been notified?

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Ancient Construction

--

Chapters
00:00 Question
01:19 Accepted answer (Score 2)
02:00 Answer 2 (Score 1)
03:16 Thank you

--

Full question
https://stackoverflow.com/questions/2993...

Answer 1 links:
[3.4's source]: https://hg.python.org/cpython/file/3.4/L...
[Condition.wait]: https://docs.python.org/3/library/thread...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #multithreading #pythonmultithreading

#avk47



ANSWER 1

Score 2


The easy way to do this is to use Python 3.2 or later, or get the backport of the current threading to 3.1/2.7/etc. from PyPI, or just copy the code for that method from, say, 3.4's source.

As the docs for Condition.wait explain:

The return value is True unless a given timeout expired, in which case it is False.

Changed in version 3.2: Previously, the method always returned None.


As a side note, I'm not sure you need a Condition here at all; you're not checking a flag inside the loop, or doing anything else that should be susceptible to a race condition, you're just waiting to be notified. That implies that, as long as you don't need magic auto-reset, an Event should be just fine. And Event.wait has had the True/False return since 2.7/3.1+, rather than 3.2+.




ACCEPTED ANSWER

Score 2


After all it was very simple, I was just focusing on the wrong thing: I just needed a sleep that could be stopped with an event and thats what Event.wait(t) does. The problem then, can be solved just with Events.

import threading
import time

def sample_thread(stop_ev):
    while not stop_ev.is_set():
        print 'Thread iteration'
        stop_ev.wait(0.1)

def main():
    stop_ev = threading.Event()
    sample_t = threading.Thread(target=sample_thread, args=(stop_ev, ))
    sample_t.start()

    # Other stuff here, sleep is just dummy
    time.sleep(14)

    stop_ev.set()

    print 'End reached.'

if __name__ == '__main__':
    main()