Skip to content
BytePatterns

Async and the Event Loop

Concurrency: lesson 7 of 10

One thread, politely taking turns.

Lesson 7 of 10 · 5 min

Async and the Event Loop

Step 1 of 10

Async runs on one thread. gather schedules both coroutines and hands that thread to the loop.

The Idea

Async concurrency runs on one thread. A coroutine executes until it hits an await, hands control back to the event loop, and the loop resumes whichever task is ready. No preemption, so no surprise interleavings — but nobody else runs while you refuse to yield.

Real-World Example

A launderette attendant working alone. Loading a machine takes a minute; the wash takes forty, and standing there watching it would be absurd. They start it, serve the next customer, and come back when the buzzer says that load is done.

The Code

import asyncio

async def worker(name, rounds):
    for step in range(1, rounds + 1):
        print(name, "step", step)
        await asyncio.sleep(0)       # yield: let the loop run someone else

async def main():
    await asyncio.gather(worker("A", 2), worker("B", 2))

asyncio.run(main())
# A step 1
# B step 1
# A step 2
# B step 2

Your turn

Put the steps in the right order.

  1. The loop resumes whichever task became ready first
  2. main() runs and gather schedules both coroutines
  3. A runs to its first await and hands control back
  4. B gets the thread while A is suspended

Mini quiz

1 / 3

A coroutine gives up control: