Concurrency with AsyncIO
Python's asyncio is the key to building high-performance web servers and IO-bound applications. It's not multi-threading; it's cooperative multitasking on a single thread.
The Event Loop
The Event Loop is the engine. It schedules tasks and pauses them when they wait for IO (network, disk), switching to other tasks in the meantime.
python codeimport asyncio async def fetch_data(id): print(f"Task {id} starting...") await asyncio.sleep(1) # Simulate network IO print(f"Task {id} finished!") return {"id": id, "data": "value"} async def main(): # Run tasks concurrently results = await asyncio.gather( fetch_data(1), fetch_data(2), fetch_data(3) ) print(results) asyncio.run(main())
Async vs Threads vs Multiprocessing
- AsyncIO: Single thread, low overhead. Best for Network IO (thousands of connections).
- Threading: OS-level threads. Subject to the Global Interpreter Lock (GIL). Good for some IO but higher memory overhead.
- Multiprocessing: Multiple processes, multiple GILs. Only way to achieve true parallelism for CPU-bound tasks.
Why use await?
The await keyword tells the loop: "I'm waiting for this to finish, feel free to run other tasks while I'm stuck." If you call a synchronous (blocking) function inside an async function, you block the entire event loop.
Industry Tip
Use anyio or httpx instead of requests when working with async code, as requests is blocking and will kill your performance gains.