事件循环(Event Loop)是 asyncio 异步编程的核心机制,可以把它理解为一个"任务调度器"。
形象比喻
想象一个餐厅服务员:
- 传统同步方式:服务员给A桌点餐后,站在厨房等菜做好,才去服务B桌(串行)
- 事件循环方式:服务员给A桌点餐后,立即去服务B桌、C桌,哪桌的菜好了就去哪桌上菜(并发)
事件循环就是这个"服务员",不断巡视所有任务,哪个任务准备好了就执行哪个。
工作原理
while True: # 事件循环的简化伪代码
# 1. 检查有哪些任务可以运行
ready_tasks = check_ready_tasks()
# 2. 执行准备好的任务
for task in ready_tasks:
task.run()
# 遇到 await 时,任务主动让出控制权
if task.has_await:
task.pause() # 暂停,等待 I/O 完成
# 3. 检查 I/O 操作是否完成
completed_io = check_io_completion()
# 4. 唤醒等待 I/O 的任务
for task in completed_io:
task.resume()
实际例子
import asyncio
async def task1():
print("任务1开始")
await asyncio.sleep(1) # ← 这里让出控制权
print("任务1结束")
async def task2():
print("任务2开始")
await asyncio.sleep(1) # ← 这里让出控制权
print("任务2结束")
async def main():
await asyncio.gather(task1(), task2())
asyncio.run(main())
执行流程:
- 事件循环启动任务1,打印"任务1开始"
- 遇到
await asyncio.sleep(1),任务1让出控制权 - 事件循环切换到任务2,打印"任务2开始"
- 遇到
await asyncio.sleep(1),任务2让出控制权 - 事件循环空闲,等待1秒
- 1秒后,两个任务都准备好了,依次恢复执行
- 打印"任务1结束"和"任务2结束"
关键点
- 单线程:事件循环运行在单个线程中,通过快速切换任务实现"并发"
- 协作式调度:任务必须主动
await让出控制权,事件循环才能调度其他任务 - 非阻塞:适合 I/O 密集型任务(网络请求、文件读写),不适合 CPU 密集型任务
为什么需要事件循环?
没有事件循环,异步代码就无法运行:
async def test():
await asyncio.sleep(1)
return "done"
# 错误:不能直接调用协程
result = test() # 这只是创建了协程对象,不会执行
# 正确:需要事件循环来运行
result = asyncio.run(test()) # asyncio.run 会创建事件循环并运行协程
总结
事件循环 = 一个永不停歇的调度器,负责管理和切换所有异步任务,让它们看起来"同时"运行。
335



被折叠的 条评论
为什么被折叠?



