- Allows one task to run while another is waiting on I/O (network, disk, timers).
- Uses concurrency, not parallelism by default (single-threaded event loop).
- Improves throughput by avoiding idle waiting.
- Best suited for I/O-bound workloads.
- Manages many waiting tasks efficiently.
- Tasks voluntarily pause with
awaitand resume later. - Low overhead, highly scalable for network / file operations.
- Share the same memory space.
- Useful for blocking I/O with shared data.
- Limited for CPU-bound work in CPython due to the GIL.
- Separate memory spaces, true parallel execution.
- Best for CPU-intensive workloads.
- Higher overhead, safer isolation.
- Central scheduler that:
- Runs coroutines
- Switches tasks when they
await - Resumes them when I/O is ready
- Never blocks — coroutines must yield control.
- Defined with
async def - Pause execution at
awaitand resume later - Lightweight and memory-efficient compared to threads
- Do nothing until:
awaited- or scheduled as a Task
- Run external programs in separate OS processes.
- Used for:
- Isolation
- True parallel CPU execution
- In asyncio:
asyncio.create_subprocess_exec
- A Task wraps a coroutine and schedules it on the event loop.
- Starts executing immediately when created.
- Enables background execution and concurrency.
- Runs multiple coroutines concurrently.
- Waits for all to finish.
- Returns results in the order they were passed.
- Default:
- If one coroutine raises an exception → others are cancelled and the exception is raised.
- With
return_exceptions=True:- All coroutines complete.
- Exceptions are returned as values.
- Structured concurrency (Python 3.11+).
- Manages multiple related tasks safely.
- If one task fails:
- All remaining tasks are cancelled automatically.
- Ensures no leaked background tasks.
- Uses
async withcontext manager. - Best for robust, production-grade async code.
- A placeholder object representing a result that will be available later.
- Used internally by the event loop and Tasks.
- Can be awaited to get the final value or exception.
Tools to coordinate access between coroutines:
asyncio.Lock— mutual exclusion (protect shared resources)asyncio.Semaphore— limit concurrent accessasyncio.Event— signal between tasksasyncio.Condition— advanced coordination
Used to prevent race conditions and data corruption.
- Coroutine → pausable function
- Task → scheduled, running coroutine
- Event loop → scheduler / traffic controller
- Gather → run many and wait for all
- TaskGroup → safe, structured concurrency