# 协程 协程(Coroutine)是用户态的轻量级线程,由程序自身控制调度,通过协作式多任务实现并发。它能在单线程内挂起和恢复执行,无需操作系统介入,切换开销极小,尤其适合 ​​I/O 密集型任务​​(如网络请求、文件读写)。 **与线程/进程对比**: - ​**​资源消耗**​​:协程内存占用更低(共享进程内存),线程需独立栈空间,进程资源消耗最大 - ​**​切换开销​**​:协程切换在用户态完成,速度极快;线程/进程切换依赖操作系统,开销较大 - **适用场景**​​:协程适合高并发 I/O 操作;线程适合 CPU 密集型任务;进程适合多核并行计算 **核心优势**: - **高并发**​​:单线程可处理数千级并发连接(如 Web 服务器) - **无锁机制​**​:避免多线程同步问题(如死锁、竞态条件) - **代码简洁​**​:用同步语法写异步逻辑,避免回调地狱 # 实现方式 ## 生成器函数 通过 yield 暂停执行并传递值:需要手动管理状态,适用简单场景 ```python def simple_coroutine(): print("协程启动") x = yield # 暂停点,等待外部传入值 print(f"接收值: {x}") coro = simple_coroutine() next(coro) # 启动协程,执行到第一个 yield coro.send(10) # 恢复执行,x 赋值为 10 ``` ## async/await 通过 asyncio 库实现异步编程 ```python import asyncio async def fetch_data(url): print(f"请求 {url}") await asyncio.sleep(1) # 挂起协程,让出控制权给事件循环,模拟异步等待 return f"来自 {url} 的数据" async def main(): tasks = [fetch_data("url1"), fetch_data("url2")] results = await asyncio.gather(*tasks) # 实现多任务并发调度:并发执行 print(results) if __name__ == "__main__": asyncio.run(main()) ``` # 基本语法 **定义协程函数** 使用 `async def` 声明协程函数 ```python import asyncio async def my_coroutine(): print("协程开始") await asyncio.sleep(1) # 模拟 I/O 操作 print("协程结束") ``` **运行协程** 协程需要通过**事件循环**执行 ```python async def main(): await my_coroutine() # 等待协程完成 if __name__ == "__main__": asyncio.run(main()) ``` # 事件循环 事件循环是协程的调度核心,负责执行、切换和监控协程任务 ```python import asyncio async def task1(): print("任务1开始") await asyncio.sleep(2) print("任务1结束") async def task2(): print("任务2开始") await asyncio.sleep(1) print("任务2结束") async def main(): await asyncio.gather(task1(), task2()) # 并发执行多个协程 if __name__ == "__main__": asyncio.run(main()) ``` # 进阶用法 ## 任务 将协程封装为任务,更灵活地控制执行 ```python async def main(): task = asyncio.create_task(my_coroutine()) # 创建任务 await task # 等待任务完成 ``` ## 超时控制 设置协程执行的超时时间 ```python async def slow_task(): await asyncio.sleep(10) async def main(): try: await asyncio.wait_for(slow_task(), timeout=3) except asyncio.TimeoutError: print("任务超时") ``` ## 协程同步 使用锁 `Lock` 保护共享资源 ```python lock = asyncio.Lock() async def safe_write(): async with lock: # 异步上下文管理器 # 安全地操作共享资源 pass ``` # 课后作业 - [必须] 动手完成本章节案例 - [扩展] 阅读官方文档相关章节 - [扩展] 用协程实现进程章节的爬虫案例