跳到主要内容

Python asyncio 异步编程

欢迎学习 Python asyncio 异步编程!本教程将带你从零基础开始,全面掌握 Python 异步编程的核心知识和实战技能。

什么是 asyncio?

asyncio 是 Python 3.4 引入的标准库,用于编写并发代码。它使用 async/await 语法,让开发者能够以同步代码的风格编写异步程序。

asyncio 是多个 Python 异步框架的基础,包括高性能网络服务器、Web 框架、数据库连接库、分布式任务队列等。

核心特点

  • 协程支持:使用 async def 定义协程,await 等待异步操作
  • 事件循环:单线程事件循环管理所有异步任务
  • 非阻塞 I/O:网络请求、文件操作等不会阻塞程序执行
  • 结构化并发:TaskGroup 等机制确保任务安全执行
  • 丰富的同步原语:Lock、Event、Semaphore、Queue 等

同步 vs 异步

理解同步和异步的区别是掌握 asyncio 的第一步:

同步编程:代码按顺序执行,每个操作完成后再执行下一个。

import time

def fetch_data():
time.sleep(1) # 阻塞等待
return "数据"

def main():
data1 = fetch_data() # 等待 1 秒
data2 = fetch_data() # 再等待 1 秒
print(data1, data2)

main() # 总耗时约 2 秒

异步编程:多个操作可以"并行"进行,等待时执行其他任务。

import asyncio

async def fetch_data():
await asyncio.sleep(1) # 非阻塞等待
return "数据"

async def main():
# 同时发起两个请求
task1 = asyncio.create_task(fetch_data())
task2 = asyncio.create_task(fetch_data())

data1 = await task1
data2 = await task2
print(data1, data2)

asyncio.run(main()) # 总耗时约 1 秒

异步编程的核心优势在于:当一个任务在等待(如网络请求、磁盘 I/O)时,程序可以切换到其他任务执行,从而提高整体效率。

适用场景

asyncio 特别适合以下场景:

场景说明
网络爬虫同时抓取多个网页
Web 服务器处理大量并发请求
API 客户端并发调用多个外部 API
数据库操作异步数据库查询
实时通信WebSocket、聊天服务器
微服务调用并发调用多个后端服务

不适合的场景:CPU 密集型任务(计算密集型操作),这类任务应使用多进程(multiprocessing)。

asyncio 的核心组件

asyncio 提供了层次分明的 API 结构:

高层 API

应用开发者主要使用这些 API:

  • 协程与任务async defawaitcreate_taskgatherTaskGroup
  • 异步队列QueuePriorityQueueLifoQueue
  • 同步原语LockEventConditionSemaphoreBarrier
  • 异步上下文管理器async with 语法
  • 异步迭代器async for 语法

低层 API

库和框架开发者使用这些 API:

  • 事件循环get_event_looprun_until_complete
  • 传输与协议:自定义底层协议
  • Future 对象:底层异步操作结果

本教程主要关注高层 API,这是大多数应用开发所需的。

为什么学习 asyncio?

1. 现代 Python 开发的标配

Python 3.7+ 正式将 async/await 作为关键字,异步编程已成为 Python 生态的重要组成部分。主流框架纷纷支持异步:

  • Web 框架:FastAPI、Starlette、Sanic、aiohttp
  • 数据库:asyncpg、aiomysql、motor(MongoDB)
  • HTTP 客户端:aiohttp、httpx
  • 任务队列:arq、dramatiq

2. 性能提升

对于 I/O 密集型应用,异步编程可以显著提升并发性能:

# 同步方式:顺序请求 100 个 URL
import requests
import time

urls = [f"https://api.example.com/{i}" for i in range(100)]

start = time.time()
for url in urls:
requests.get(url) # 每个请求等待响应
print(f"同步耗时: {time.time() - start:.2f} 秒") # 约 100 秒

# 异步方式:并发请求 100 个 URL
import aiohttp
import asyncio

async def fetch(session, url):
async with session.get(url) as response:
return await response.text()

async def main():
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in urls]
await asyncio.gather(*tasks)

start = time.time()
asyncio.run(main())
print(f"异步耗时: {time.time() - start:.2f} 秒") # 约 1-2 秒

3. 更好的资源利用

异步程序在单线程中运行,避免了线程切换的开销和 GIL(全局解释器锁)的限制。一个异步程序可以用极低的资源处理数千个并发连接。

学习路径

基础阶段              核心阶段              进阶阶段              实战阶段
│ │ │ │
▼ ▼ ▼ ▼
协程概念 ──▶ 任务与并发 ──▶ 同步原语 ──▶ Web 应用
async/await ──▶ gather/wait ──▶ Lock/Semaphore ──▶ FastAPI
事件循环 ──▶ TaskGroup ──▶ Queue ──▶ 爬虫开发
第一个程序 ──▶ 超时控制 ──▶ 异步上下文管理器 ──▶ 数据库操作

教程目录

基础入门

  • 协程基础 - 理解协程、async/await 语法、运行协程
  • 事件循环 - 事件循环的工作原理、调度回调、信号处理、多线程与事件循环

核心功能

  • 任务与并发 - 创建任务、TaskGroup、并发执行、取消与超时、shield 保护

同步原语

  • 同步原语 - Lock、Event、Condition、Semaphore、Barrier、Queue

异步 I/O

高级主题

实战应用

  • 最佳实践 - 常见陷阱、性能优化、eager_task_factory、调试技巧
  • 速查表 - 常用 API 快速参考

前置知识

学习 asyncio 前需要掌握:

  • Python 基础:函数、类、装饰器、上下文管理器
  • 迭代器与生成器yield__iter____next__
  • 并发概念:进程、线程、并发的区别

开发环境

  • Python 3.8+(推荐 3.11+,支持 TaskGroup)
  • 支持 async/await 语法高亮的编辑器(VS Code、PyCharm)

快速体验

在命令行启动 asyncio REPL,直接体验异步编程:

python -m asyncio
asyncio REPL 3.11.0
Use "await" directly instead of "asyncio.run()".
>>> import asyncio
>>> await asyncio.sleep(1, result="hello")
'hello'

参考资料

准备好开始学习了吗?让我们从协程基础开始,深入理解异步编程的核心概念。