Python中的协程与异步编程
字数 718 2025-11-03 08:33:38
Python中的协程与异步编程
描述:
协程(Coroutine)是Python中实现异步编程的核心机制,允许函数在执行过程中暂停并恢复,避免阻塞线程。它通过async和await关键字实现,常用于高并发I/O密集型任务(如网络请求、文件操作)。与多线程相比,协程由事件循环(Event Loop)驱动,资源开销更小。
解题过程:
-
同步与异步的基本区别
- 同步代码按顺序执行,遇到I/O操作(如请求网络数据)时,线程会等待操作完成,导致资源闲置。
- 异步代码在遇到I/O操作时,会暂停当前任务,让事件循环去执行其他任务,待I/O完成后恢复执行。
- 示例对比:
# 同步方式(阻塞) import time def fetch_data(): time.sleep(2) # 模拟I/O阻塞 return "数据" # 异步方式(非阻塞) import asyncio async def async_fetch_data(): await asyncio.sleep(2) # 模拟异步I/O return "数据"
-
协程的定义与执行
- 使用
async def定义协程函数,调用时会返回协程对象(不立即执行)。 - 必须通过事件循环(如
asyncio.run())或await触发执行:async def main(): result = await async_fetch_data() # 等待协程完成 print(result) asyncio.run(main()) # 启动事件循环
- 使用
-
事件循环的作用
- 事件循环是协程的调度中心,负责在多个协程之间切换执行。
- 当协程遇到
await时,事件循环会挂起该协程,执行其他可运行的任务。 - 示例:同时执行多个协程
async def task(name, delay): await asyncio.sleep(delay) print(f"{name} 完成") async def main(): # 创建多个协程任务 tasks = [ asyncio.create_task(task("A", 2)), asyncio.create_task(task("B", 1)) ] await asyncio.gather(*tasks) # 并发执行所有任务 asyncio.run(main()) # 输出:B 完成 → A 完成(B先完成,因为延迟更短)
-
异步I/O的实际应用
- 使用
aiohttp库实现异步HTTP请求:import aiohttp async def fetch_url(url): async with aiohttp.ClientSession() as session: async with session.get(url) as response: return await response.text() async def main(): urls = ["http://example.com", "http://example.org"] results = await asyncio.gather(*[fetch_url(url) for url in urls]) print(results) # 并发获取所有URL的内容
- 使用
-
关键注意事项
- 避免在协程中使用阻塞操作(如
time.sleep()),需用异步替代(asyncio.sleep())。 - 协程之间通过
await协作,而非并行执行(单线程内并发)。 - 异常处理需使用
try...except包裹await调用。
- 避免在协程中使用阻塞操作(如
总结:
协程通过事件循环和async/await机制,将I/O等待时间转化为执行其他任务的机会,显著提升并发效率。掌握协程需理解其与同步代码的差异、事件循环的调度逻辑,以及正确使用异步库。