TIL - Python's asyncio.Event Lets Coroutines Signal Each Other Without Polling
asyncio.Event is a lightweight one-time signal: coroutines await event.wait() and block until another coroutine calls event.set() - no busy-waiting, no shared booleans guarded by locks.
import asyncio
async def worker(name: str, ready: asyncio.Event):
print(f"{name}: waiting for start signal")
await ready.wait()
print(f"{name}: started work")
await asyncio.sleep(0.1)
print(f"{name}: done")
async def main():
ready = asyncio.Event()
tasks = [asyncio.create_task(worker(f"W{i}", ready)) for i in range(3)]
await asyncio.sleep(0.2) # simulate startup delay
print("Controller: firing start signal")
ready.set() # unblocks ALL waiting coroutines at once
await asyncio.gather(*tasks)
asyncio.run(main())
# W0, W1, W2 all wait, then all start simultaneously after ready.set()Event.clear() resets the flag so it can be reused. For more complex signalling where you need to notify one waiter at a time and pass a condition, reach for asyncio.Condition instead.