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 tasyncio.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 tTaskGroup — 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 反馈 — 无需本地设置。
此课程中的所有课时
- 协程与事件循环
- await、任务与汇集
- 异步上下文管理器与迭代器
- 生产环境中的异步 I/O 模式