Asyncio Events and Conditions: The Secret Life of Python's Traffic Signals

Dmitry Posokhov - Oct 7 - - Dev Community

Ever wondered how your Python coroutines manage to play nicely together without causing a traffic jam? Let's dive into the whimsical world of asyncio events and conditions—the unsung heroes keeping your asynchronous code from turning into a circus (unless you want it to).

Events: The Green Light Everyone's Waiting For
Think of an asyncio.Event as a traffic light in your code. Coroutines line up and wait patiently (or not so patiently) for the light to turn green before zooming off.

Imagine you're at a crosswalk with a group of people (coroutines). The pedestrian signal is red (event is unset), so everyone waits. The moment it turns green (event.set()), the entire group moves forward in unison. No one wants to be that person dodging cars because they went ahead on a red light.

import asyncio

async def pedestrian(event):
    print("Pedestrian is waiting for the signal.")
    await event.wait()
    print("Pedestrian crosses the street.")

async def traffic_light(event):
    print("Traffic light is red.")
    await asyncio.sleep(2)
    event.set()
    print("Traffic light turns green.")

async def main():
    event = asyncio.Event()
    await asyncio.gather(pedestrian(event), traffic_light(event))

asyncio.run(main())
Enter fullscreen mode Exit fullscreen mode

Output:

Pedestrian is waiting for the signal.
Traffic light is red.
Traffic light turns green.
Pedestrian crosses the street.
Enter fullscreen mode Exit fullscreen mode

Conditions: The VIP Pass at the Club
asyncio.Condition is like that bouncer at the exclusive club. Not only do you need the club to be open (with condition), but you also need to meet certain criteria (await condition.wait()).

Picture trying to get into a trendy nightclub. The club (condition) has limited capacity, and the bouncer only lets you in if someone else leaves (a condition is met). You might wait outside, practicing your best dance moves (or checking your phone awkwardly), until you get the nod.

import asyncio

async def clubber(condition, name):
    async with condition:
        print(f"{name} wants to enter the club.")
        await condition.wait()
        print(f"{name} enters the club.")

async def bouncer(condition):
    await asyncio.sleep(2)
    async with condition:
        print("Bouncer signals someone can enter.")
        condition.notify()

async def main():
    condition = asyncio.Condition()
    await asyncio.gather(
        clubber(condition, "Alice"),
        clubber(condition, "Bob"),
        bouncer(condition)
    )

asyncio.run(main())
Enter fullscreen mode Exit fullscreen mode

Output:

Alice wants to enter the club.
Bob wants to enter the club.
Bouncer signals someone can enter.
Alice enters the club.
Enter fullscreen mode Exit fullscreen mode

In this example, only one clubber gets to enter the club because the bouncer only signals one person (condition.notify()). The other clubber remains waiting indefinitely. If you want everyone to get in (party time!), you can use condition.notify_all().

import asyncio

async def clubber(condition, name):
    async with condition:
        print(f"{name} wants to enter the club.")
        await condition.wait()
        print(f"{name} enters the club.")

async def bouncer(condition):
    await asyncio.sleep(2)
    async with condition:
        print("Bouncer signals everyone can enter.")
        condition.notify_all()

async def main():
    condition = asyncio.Condition()
    await asyncio.gather(
        clubber(condition, "Alice"),
        clubber(condition, "Bob"),
        bouncer(condition)
    )

asyncio.run(main())
Enter fullscreen mode Exit fullscreen mode

Output:

Alice wants to enter the club.
Bob wants to enter the club.
Bouncer signals everyone can enter.
Alice enters the club.
Bob enters the club.
Enter fullscreen mode Exit fullscreen mode

Wrapping Up the Party
By now, you should have a clearer understanding of how asyncio events and conditions work. They're the behind-the-scenes coordinators ensuring everything runs smoothly.

So the next time your asynchronous code doesn't resemble a pile-up on the freeway, you know who to thank!

. . .
Terabox Video Player