0Pricing
Python Academy · 课时

await、任务与汇集

使用 await、asyncio.create_task 和 asyncio.gather 实现并发。

await、任务与汇集 是 CoddyKit 上的免费 Python Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Python Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Python Academy 课程共包含 4 节课。

await 与顺序执行

单独使用 await 会按顺序运行协程。要并发运行协程,请将它们包装为任务。

import asyncio

async def main():
    # Sequential — total ~3 s
    await asyncio.sleep(2)
    await asyncio.sleep(1)

    # Concurrent using gather — total ~2 s
    await asyncio.gather(asyncio.sleep(2), asyncio.sleep(1))

asyncio.create_task()

asyncio.create_task(coro) 会调度一个协程,使其作为独立任务与当前协程并发运行。

import asyncio

async def work(n):
    await asyncio.sleep(n)
    return n

async def main():
    t1 = asyncio.create_task(work(2))
    t2 = asyncio.create_task(work(1))
    r1 = await t1
    r2 = await t2
    print(r1, r2)   # 2 1 (total ~2 s)

asyncio.run(main())

asyncio.gather()

asyncio.gather(*coros) 会并发运行多个协程,并在它们全部完成后按原顺序返回所有结果。

import asyncio

async def fetch(i):
    await asyncio.sleep(1)
    return f"data-{i}"

async def main():
    results = await asyncio.gather(fetch(1), fetch(2), fetch(3))
    print(results)  # ["data-1", "data-2", "data-3"] in ~1 s

asyncio.run(main())

gather 与 return_exceptions

设置 return_exceptions=True,这样失败的协程会将其异常作为结果返回,而不会取消整个 gather 操作。

import asyncio

async def risky(n):
    if n == 2: raise ValueError("bad")
    return n

async def main():
    results = await asyncio.gather(
        risky(1), risky(2), risky(3),
        return_exceptions=True
    )
    print(results)   # [1, ValueError("bad"), 3]

asyncio.wait()

asyncio.wait(tasks, return_when=...) 返回两个集合:done 和 pending。使用 FIRST_COMPLETED 可以对第一个结果作出响应。

import asyncio

async def slow(): await asyncio.sleep(3); return "slow"
async def fast(): await asyncio.sleep(1); return "fast"

async def main():
    tasks = {asyncio.create_task(slow()), asyncio.create_task(fast())}
    done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
    for t in pending: t.cancel()

任务取消

调用 task.cancel() 请求取消。任务会在下一个 await 点接收到 asyncio.CancelledError。

import asyncio

async def long_job():
    try:
        await asyncio.sleep(100)
    except asyncio.CancelledError:
        print("Cancelled!")
        raise   # re-raise is required

async def main():
    t = asyncio.create_task(long_job())
    await asyncio.sleep(1)
    t.cancel()
    await t

asyncio.timeout() — Python 3.11+

使用 asyncio.timeout(seconds) 包装 await 操作,如果操作耗时过长,就会取消该操作。

import asyncio

async def main():
    try:
        async with asyncio.timeout(2):
            await asyncio.sleep(10)   # too slow
    except TimeoutError:
        print("Timed out!")

asyncio.wait_for()

对于 Python < 3.11,请使用 asyncio.wait_for(coro, timeout=N) 添加 timeout,并引发 asyncio.TimeoutError。

import asyncio

async def slow(): await asyncio.sleep(5)

async def main():
    try:
        await asyncio.wait_for(slow(), timeout=2)
    except asyncio.TimeoutError:
        print("Timed out")

任务名称与检查

使用 asyncio.create_task(coro, name="...") 为任务命名,以便调试,并使用 task.get_name() 进行检查。

import asyncio

async def worker(): await asyncio.sleep(1)

async def main():
    t = asyncio.create_task(worker(), name="worker-1")
    print(t.get_name())   # worker-1
    await t

TaskGroup — Python 3.11+

asyncio.TaskGroup 会创建结构化的任务组。如果任何任务引发异常,所有任务都会被取消。

import asyncio

async def main():
    async with asyncio.TaskGroup() as tg:
        t1 = tg.create_task(asyncio.sleep(1))
        t2 = tg.create_task(asyncio.sleep(2))
    # all tasks done here

使用 Semaphore 进行速率限制

使用 asyncio.Semaphore(n) 限制并发操作的数量(例如 API 调用)。

import asyncio

sem = asyncio.Semaphore(5)  # max 5 concurrent

async def limited_fetch(url):
    async with sem:
        await fetch(url)   # at most 5 at a time

快速检查

await coro() 与 asyncio.create_task(coro()) 之间有什么区别?

回顾

使用 create_task 或 gather 进行并发执行。gather 收集所有结果;wait 提供更细粒度的控制。使用 .cancel() 取消任务,并使用 wait_for 或 asyncio.timeout 应用 timeout。

常见问题解答

「await、任务与汇集」课时是免费的吗?

是的 — 「await、任务与汇集」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Python Academy 课程的其余内容,请升级到 CoddyKit PRO。 Python Academy 课程共包含 4 节课。

「await、任务与汇集」这节课中我会学到什么?

使用 await、asyncio.create_task 和 asyncio.gather 实现并发。 你通过在浏览器中直接运行的动手代码来练习 Python Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Python Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Python Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「await、任务与汇集」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Python Academy 课中编写并运行代码吗?

能。每节 Python Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 协程与事件循环
  2. await、任务与汇集
  3. 异步上下文管理器与迭代器
  4. 生产环境中的异步 I/O 模式
← 返回 Python Academy