Reputation: 47
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.
Upvotes: 0
Views: 1386
Reputation: 479
For Python 3.10
To make sure the lock is release no matter what. We can use try--finally.
like
await cond.acquire()
try:
await cond.wait()
finally:
cond.release()
And we already have a convenient way (context manager) to do that:
async with cond:
await cond.wait()
notify()
and notify_all()
also need the lock.
async with cond:
cond.notify_all()
Upvotes: 0
Reputation: 429
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 await
ing 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())
Upvotes: 1