pythonpython-3.xpython-asyncio

Python asyncio wait and notify


I am trying to do something similar like C# ManualResetEvent but in Python.

I have attempted to do it in python but doesn't seem to work.

import asyncio

cond = asyncio.Condition()

async def main():
    some_method()

    cond.notify()

async def some_method():
    print("Starting...")
    
    await cond.acquire()
    await cond.wait()
    cond.release()
    
    print("Finshed...")

main()

I want the some_method to start then wait until signaled to start again.


Solution

  • This code is not complete, first of all you need to use asyncio.run() to bootstrap the event loop - this is why your code is not running at all.

    Secondly, some_method() never actually starts. You need to asynchronously start some_method() using asyncio.create_task(). When you call an "async def function" (the more correct term is coroutinefunction) it returns a coroutine object, this object needs to be driven by the event loop either by you awaiting it or using the before-mentioned function.

    Your code should look more like this:

    import asyncio
    
    async def main():
        cond = asyncio.Condition()
    
        t = asyncio.create_task(some_method(cond))
    
        # The event loop hasn't had any time to start the task
        # until you await again. Sleeping for 0 seconds will let
        # the event loop start the task before continuing.
        await asyncio.sleep(0)
        cond.notify()
    
        # You should never really "fire and forget" tasks,
        # the same way you never do with threading. Wait for
        # it to complete before returning:
        await t
    
    async def some_method(cond):
        print("Starting...")
        
        await cond.acquire()
        await cond.wait()
        cond.release()
        
        print("Finshed...")
    
    asyncio.run(main())