Condition.notify_all wakes every coroutine currently waiting on an asyncio condition. A notifying coroutine acquires the condition, calls notify_all, and lets waiting workers resume and reacquire the lock before doing work. section 11.5
The basic coordination pattern is:
- Workers acquire the condition and await condition.wait(). section 11.5
- A notifier acquires the same condition and calls notify_all(). section 11.5
- All waiting workers wake, reacquire the lock, and continue their work. section 11.5
Two workers waiting for an event
Two do_work coroutines wait on a condition while fire_event sleeps for several seconds. After acquiring the condition, fire_event calls notify_all; both workers wake and perform their work. section 11.5
Listing 11.14 Condition basics
import asyncio
from asyncio import Condition
async def do_work(condition: Condition):
while True:
print('Waiting for condition lock...')
async with condition: #1
print('Acquired lock, releasing and waiting for condition...')
await condition.wait() #2
print('Condition event fired, re-acquiring lock and doing work...')
await asyncio.sleep(1)
print('Work finished, lock released.') #3
async def fire_event(condition: Condition):
while True:
await asyncio.sleep(5)
print('About to notify, acquiring condition lock...')
async with condition:
print('Lock acquired, notifying all workers.')
condition.notify_all() #4
print('Notification finished, releasing lock.')
async def main():
condition = Condition()
asyncio.create_task(fire_event(condition))
await asyncio.gather(do_work(condition), do_work(condition))
asyncio.run(main())
Inspect the runnable Condition pattern, including async lock acquisition, waiting, notification, and lock release. section 11.5
