Python中的协程(Coroutine)与异步编程底层实现(asyncio库详解)
字数 749 2025-11-25 01:43:57
Python中的协程(Coroutine)与异步编程底层实现(asyncio库详解)
1. 协程基础概念
- 协程是一种用户态的轻量级线程,由程序自身控制调度(非操作系统线程)
- 核心特点:能在特定位置暂停执行(yield)和恢复执行(send)
- 与线程对比:协程切换成本更低(无内核态切换),适合I/O密集型任务
2. 生成器到协程的演进
# 传统生成器(单向数据流)
def simple_generator():
yield 1
yield 2
# 协程(支持双向通信)
def simple_coroutine():
x = yield "请发送数据"
print(f"收到数据: {x}")
yield "处理完成"
3. asyncio核心组件
- 事件循环(Event Loop):协程调度中心,检测就绪任务并执行
- 协程函数(async def):使用async关键字定义的协程
- 可等待对象(Awaitable):包括协程、Task、Future
- Task:对协程的包装,用于并发调度
4. 事件循环工作流程
启动事件循环 → 获取就绪任务 → 执行协程 → 遇到await暂停 → 注册回调 → 切换任务
↑___________________________________________________________↓
5. async/await语法详解
import asyncio
async def demo_coroutine():
print("开始执行")
# await将控制权交还事件循环
await asyncio.sleep(1)
print("恢复执行")
# 运行协程的三种方式
# 方式1:asyncio.run(推荐)
asyncio.run(demo_coroutine())
# 方式2:手动管理事件循环
loop = asyncio.get_event_loop()
loop.run_until_complete(demo_coroutine())
# 方式3:创建Task并发执行
async def main():
task = asyncio.create_task(demo_coroutine())
await task
6. Future对象机制
- Future是底层异步操作结果的占位符
- 包含状态(pending/fulfilled/cancelled)和结果值
- await实际是在等待Future对象的完成
async def future_demo():
loop = asyncio.get_running_loop()
future = loop.create_future()
# 模拟异步设置结果
loop.call_later(1, future.set_result, "完成!")
result = await future # 此处暂停直到future有结果
print(result)
7. Task调度原理
- Task是Future的子类,包装协程的执行
- 创建Task时协程立即加入事件循环调度
async def task_demo():
# 创建任务后立即返回,不阻塞
task1 = asyncio.create_task(asyncio.sleep(1))
task2 = asyncio.create_task(asyncio.sleep(2))
# 等待多个任务完成
await asyncio.gather(task1, task2)
8. 异步I/O实现机制
- 基于选择器(selector)监控文件描述符
- 使用回调函数通知事件就绪
- 与操作系统I/O多路复用接口对接(epoll/kqueue/select)
9. 协程执行状态机
创建 → 挂起(Suspended) → 运行(Running) → 完成(Done)
↑_____________await___________↓
10. 实际工作流程示例
import asyncio
async def fetch_data(delay, id):
print(f"任务{id}开始")
await asyncio.sleep(delay) # 模拟I/O操作
print(f"任务{id}完成")
return id
async def main():
# 并发执行三个任务
tasks = [
asyncio.create_task(fetch_data(1, 1)),
asyncio.create_task(fetch_data(2, 2)),
asyncio.create_task(fetch_data(1, 3))
]
# 等待所有任务完成
results = await asyncio.gather(*tasks)
print(f"所有任务完成: {results}")
asyncio.run(main())
11. 关键设计模式
- 回调模式:通过add_done_callback注册完成回调
- 异步上下文管理器:async with语句管理异步资源
- 异步迭代器:async for处理异步数据流
通过这种底层实现,asyncio在单线程内实现了高并发I/O处理,避免了多线程的锁竞争和上下文切换开销。