Python中的协程(Coroutine)与异步编程
字数 661 2025-11-03 20:46:32
Python中的协程(Coroutine)与异步编程
一、协程的基本概念
- 定义:协程是一种用户态的轻量级线程,由程序自己控制调度(而非操作系统内核)
- 特点:
- 执行过程中可以暂停(挂起),并在需要时恢复执行
- 协程间的切换不涉及线程上下文切换,开销远小于线程切换
- 单线程内可运行多个协程,实现并发效果
二、协程的演进过程
- 生成器基础(Python 3.4之前)
def simple_coroutine():
print("启动协程")
x = yield # 暂停点,接收外部传入的值
print("接收到值:", x)
# 使用方式
coro = simple_coroutine()
next(coro) # 启动协程,执行到第一个yield
coro.send(42) # 向协程发送值,恢复执行
- 引入asyncio库(Python 3.4)
import asyncio
@asyncio.coroutine # 装饰器标记协程
def old_style_coroutine():
yield from asyncio.sleep(1) # 委托给其他生成器
print("执行完成")
三、async/await语法(Python 3.5+)
-
关键字定义:
async def:声明异步函数(协程函数)await:等待异步操作完成,期间协程暂停但不会阻塞事件循环
-
基本语法示例:
import asyncio
async def say_after(delay, message):
await asyncio.sleep(delay) # 异步等待
print(message)
async def main():
# 顺序执行
await say_after(1, "Hello")
await say_after(1, "World")
# 并发执行
task1 = asyncio.create_task(say_after(1, "Task1"))
task2 = asyncio.create_task(say_after(1, "Task2"))
await task1
await task2
# 运行协程
asyncio.run(main())
四、协程的运行机制
-
事件循环(Event Loop)
- 核心调度器,管理所有协程的执行
- 不断检查可执行的协程,并在它们之间切换
- 提供异步IO、定时器等基础设施
-
协程状态转换:
- 创建:通过调用异步函数创建(但未执行)
- 挂起:遇到await表达式时暂停
- 恢复:等待的操作完成时重新进入就绪队列
- 完成:函数执行完毕或出现异常
五、异步编程实践要点
- 错误处理:
async def risky_operation():
try:
await some_async_call()
except Exception as e:
print(f"操作失败: {e}")
# 多个协程的错误处理
async def batch_operations():
results = await asyncio.gather(
task1(), task2(), task3(),
return_exceptions=True # 将异常作为结果返回
)
- 资源管理:
async def using_async_context():
async with aiofiles.open('file.txt') as f: # 异步上下文管理器
content = await f.read()
六、协程与线程的对比
-
适用场景:
- 协程:I/O密集型任务(网络请求、文件操作)
- 线程:CPU密集型任务(计算密集型操作)
-
性能特点:
- 协程:单线程内可处理数万个并发连接
- 线程:受GIL限制,适合多I/O但少CPU的场景
七、实际应用模式
- 生产者-消费者模式:
async def producer(queue):
while True:
item = await get_item()
await queue.put(item)
async def consumer(queue):
while True:
item = await queue.get()
await process_item(item)
通过这种渐进式学习,你可以从基础概念到实际应用全面掌握Python协程和异步编程的核心要点。