Loading Page Content...
Preparing courses, live labs, and learning resources.सामग्री लोड हो रही है, कृपया प्रतीक्षा करें...
Preparing courses, live labs, and learning resources.सामग्री लोड हो रही है, कृपया प्रतीक्षा करें...
While the await expression pauses the current coroutine until a single operation completes, achieving true concurrent execution requires wrapping coroutines into Tasks. An asyncio.Task schedules a coroutine on the active event loop, allowing multiple operations to interleave and run concurrently on the single thread.
Understanding task scheduling, aggregation, cancellation, and Python 3.11's modern Structured Concurrency (asyncio.TaskGroup) is essential for building production-grade asynchronous services.
asyncio.create_taskWhen you simply write:
These operations execute sequentially. fetch_b() cannot begin until fetch_a() has completed.
To execute them concurrently, wrap each coroutine with asyncio.create_task():
asyncio.gatherThe asyncio.gather() function accepts an arbitrary number of awaitables, runs them concurrently, and returns an aggregated list of their results in the exact order of submission:
return_exceptions=TrueBy default, if one task inside gather() raises an unhandled exception, gather() immediately raises that exception, but the other tasks continue running in the background (orphan tasks). Setting return_exceptions=True causes exceptions to be returned as items in the result list alongside successful values:
asyncio.TaskGroupPEP 654 and Python 3.11 introduced Structured Concurrency via asyncio.TaskGroup. It provides an asynchronous context manager that guarantees no task leaks or orphan tasks:
Tasks can be cancelled programmatically, or automatically via timeout wrappers:
| Tool | Purpose | Failure Behavior |
|---|---|---|
asyncio.create_task(coro) | Schedules a single coroutine on loop | Unhandled errors logged as task exceptions |
asyncio.gather(*awaitables) | Concurrently aggregates results | Raises first error; siblings continue running |
asyncio.TaskGroup() (3.11+) | Structured Concurrency context | Cancels all child tasks if one fails; raises ExceptionGroup |
asyncio.timeout(delay) (3.11+) | Async context manager timeout | Cancels tasks inside scope upon deadline |
task.cancel() | Cancels an individual task | Injects asyncio.CancelledError at await point |
Tasks created with asyncio.create_task() that are not retained in a strong reference (like a set) can be garbage-collected mid-execution!
asyncio.gatherBy default, if one task in asyncio.gather() raises an exception, the exception propagates immediately, but other running tasks continue in the background unless handled with return_exceptions=True.
Demonstrate canceling a slow async task using asyncio.wait_for() and gracefully catching asyncio.TimeoutError.
What is the effect of calling task = asyncio.create_task(my_coro())? A. It pauses the current function until my_coro() completes. B. It schedules my_coro() to run concurrently on the active event loop as an asyncio.Task and returns immediately. C. It compiles the coroutine to C code. D. It starts a new POSIX thread.
asyncio.create_task() packages the coroutine into a Task and registers it with the running event loop for concurrent execution, returning the Task object without blocking.What happens by default in asyncio.gather(task1, task2) if task1 raises an unhandled exception? A. task2 is immediately killed by the operating system. B. gather() immediately re-raises the exception from task1, while task2 continues running in the background as an orphaned task. C. The exception is converted into a string. D. The event loop crashes.
return_exceptions=False), gather() raises the first encountered exception immediately, but does not cancel or terminate the remaining sibling tasks.What major concurrency advancement does Python 3.11's asyncio.TaskGroup provide over older task management patterns? A. It disables the GIL across multiple threads. B. It enforces Structured Concurrency: if any child task in the group fails, all other active tasks in the group are automatically cancelled, eliminating leaked orphan tasks. C. It converts asynchronous code to GPU shaders. D. It eliminates the need for await.
asyncio.TaskGroup introduces structured concurrency, ensuring that all tasks spawned within its context block are cleanly resolved, and automatically cancelling remaining siblings if an exception occurs.When a task is cancelled via task.cancel(), what exception is raised inside the coroutine at its current await suspension point? A. StopIteration B. asyncio.CancelledError C. KeyboardInterrupt D. TimeoutError
.cancel() on an asyncio.Task injects asyncio.CancelledError into the coroutine at its active await expression.What happens if a coroutine catches asyncio.CancelledError in a try...except block and suppresses it without re-raising? A. The task refuses to cancel and continues running, violating cancellation protocols. B. The event loop shuts down. C. A SyntaxError is logged. D. Python reboots the machine.
CancelledError is caught and not re-raised, the task does not acknowledge cancellation and continues executing, which breaks structured concurrency cancellation semantics.In the next lesson, we will continue your advanced Python journey with Project: Async Web Scraper (8: Asynchronous Programming (Asyncio)).
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
| Previous Lesson | Next Lesson |
|---|---|
| Async and Await Syntax | Structured Concurrency in Asyncio: TaskGroup and asyncio.timeout() |
Test your understanding of this lesson with 5 questions. Each question has one correct answer.