Understand the event loop, coroutines vs Tasks, asyncio.gather(), Semaphore for concurrency control, and asyncio.timeout() patterns.
0 / 5 completed
1 / 5
What is the event loop in Python asyncio and how does it schedule coroutines?
Event loop:asyncio.run(main()) creates an event loop and runs the coroutine. When a coroutine awaits an I/O operation (network read, file write), the event loop suspends it and runs other pending coroutines. When the I/O completes, the event loop resumes the suspended coroutine. This achieves high concurrency with a single thread.
2 / 5
What is the difference between a coroutine and a Task in asyncio?
Coroutine vs Task:result = await fetch(url) runs fetch sequentially. task = asyncio.create_task(fetch(url)) schedules it immediately so it runs concurrently with subsequent code. Without Task, await on multiple coroutines in sequence is still sequential — each waits for the previous to complete before starting.
3 / 5
What does asyncio.gather() do and what is its error behaviour?
asyncio.gather():results = await asyncio.gather(fetch(url1), fetch(url2), fetch(url3)) runs all three concurrently. With return_exceptions=True, exceptions are returned as results instead of raised, allowing inspection of partial successes. Without it, the first exception cancels remaining tasks and propagates immediately.
4 / 5
What is an asyncio Semaphore and why is it used when making many concurrent requests?
asyncio Semaphore:sem = asyncio.Semaphore(10) limits concurrent HTTP requests to 10 at a time. async with sem: response = await session.get(url) — once 10 coroutines are inside the block, the 11th waits until one exits. Without limiting, spawning 1000 concurrent requests may exhaust file descriptors or hit API rate limits.
5 / 5
How does asyncio.timeout() (Python 3.11+) improve on previous timeout patterns?
asyncio.timeout(): older patterns used asyncio.wait_for(coro(), timeout=5) but could not wrap multiple awaits in one timeout scope. The context manager form wraps arbitrary async blocks: async with asyncio.timeout(5): await a(); await b() — the total time for both is bounded. asyncio.timeout_at(deadline) accepts an absolute time for deadline-based scheduling.