I'm writing a project using Python's asyncio
module, and I'd like to synchronize my tasks using its synchronization primitives. However, it doesn't seem to behave as I'd expect.
From the documentation, it seems that Condition.wait_for()
offers a means by which to allow a coroutine to wait for a particular user-defined condition to evaluate as true. However, on attempting to use the method, it seems to behave in ways I wouldn't expect - my condition is only checked once, and if it is found to be false, the waiting task simply hangs forever, without ever checking again. I've written a short example below to demonstrate what I'm trying to do:
#!/usr/bin/env python
import asyncio
thing = False
setter_done = None
getter_done = None
async def main():
setter_done = asyncio.Event()
getter_done = asyncio.Event()
setter = asyncio.ensure_future(set_thing())
getter = asyncio.ensure_future(get_thing())
#To avoid the loop exiting prematurely:
await setter_done.wait()
await getter_done.wait()
async def set_thing():
global thing
global setter_done
thing = False
#sleep for some arbitrary amount of time; simulate work happening
await asyncio.sleep(10)
thing = True
print("Thing was set to True!")
setter_done.set()
async def get_thing():
global thing
global getter_done
def check_thing():
print("Checking...")
return thing
c = asyncio.Condition()
await c.acquire()
await c.wait_for(check_thing)
c.release()
print("Thing was found to be true!")
getter_done.set()
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
I'd expect this to print something like the following:
Checking...
Thing was set to True!
Checking...
Thing was found to be True!
Instead, I get:
Checking...
Thing was set to True!
... (hangs indefinitely)