事件循环(Event Loop) 是理解 Python 异步编程(asyncio、协程、异步 IO)的核心概念。
它是让 “一个线程同时处理多个任务” 成为可能的关键机制。
🧠 一、事件循环是什么?
一句话总结:
事件循环就是一个“无限循环”,不断检测、调度并执行事件(任务、IO、回调)。
在 Python 的异步模型中(特别是 asyncio),事件循环 是一个调度中心,它:
1. 维护一个任务队列;
2. 等待任务“可执行”(例如 IO 就绪);
3. 把可执行的任务分配 CPU 运行一点;
4. 然后挂起等待其他任务;
5. 循环往复。
⸻
🕹️ 二、为什么需要事件循环?
传统同步模型下:
data = download()
process(data)
save(data)
如果 download() 是网络请求(耗时 3 秒),程序就会阻塞等待。
但异步模型下:
data = await download()
process(data)
await save(data)
事件循环会在等待 download() 的网络返回时,
自动切换去执行别的任务(比如另一个用户的下载)。
➡️ 这样一个线程就能同时处理成百上千个连接,实现了“并发”。
⸻
⚙️ 三、Python 中事件循环的运行机制
在 asyncio 中,事件循环负责调度所有的协程(coroutine)。
可以这样理解:
┌──────────────────────┐
│ Event Loop │
│ ┌──────────────────┐ │
│ │ coroutine A │ │
│ │ coroutine B │ │
│ │ coroutine C │ │
│ └──────────────────┘ │
│ IO selector (epoll) │
└──────────────────────┘
执行步骤(简化):
1. 注册所有协程任务(coroutines);
2. 当某个协程执行到 await,就挂起,返回控制权;
3. 事件循环检测哪个任务的“IO 已就绪”(比如网络读写完成);
4. 唤醒相应协程继续执行;
5. 重复此过程直到所有任务完成。
⸻
🧩 四、代码示例:事件循环的工作方式
import asyncio
async def task(name, delay):
print(f"{name} start")
await asyncio.sleep(delay)
print(f"{name} end")
return f"{name} result"
async def main():
t1 = asyncio.create_task(task("A", 2))
t2 = asyncio.create_task(task("B", 1))
print("Waiting for tasks...")
results = await asyncio.gather(t1, t2)
print(results)
asyncio.run(main())
输出结果(时间重叠执行):
A start
B start
Waiting for tasks...
B end
A end
['A result', 'B result']
👉 在 await asyncio.sleep() 时,协程让出控制权,事件循环会切换到另一个任务继续执行。
⸻
🧭 五、事件循环的生命周期(asyncio.run 内部原理)
asyncio.run(main()) 实际上做了三件事:
1. 创建事件循环(loop = asyncio.new_event_loop())
2. 运行主协程(loop.run_until_complete(main()))
3. 关闭事件循环(loop.close())
如果你手动控制:
import asyncio
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(main())
loop.close()
⸻
⚡ 六、事件循环的核心组成部分

⸻
🔍 七、事件循环的本质原理(类比)
假设你是一个“单线程服务员”,同时要处理 3 张桌子的客人:
1. A 桌点餐 → 厨房做菜(IO 阻塞)
2. B 桌结账 → POS 等待响应(IO 阻塞)
3. C 桌要加水 → 立刻可以执行(CPU 操作)
如果你傻等 A 桌菜上齐,B、C 都得等。
但事件循环模式下:
你接完 A 桌点餐 → 等厨房 → 去帮 B、C → 再回来看菜好了没。
➡️ 所以“异步事件循环”让一个线程看起来能同时处理多个客户。
⸻
🧮 八、底层机制(操作系统角度)
Python 的事件循环底层基于 I/O 多路复用机制,如:
• Linux:epoll
• macOS:kqueue
• Windows:IOCP
事件循环通过这些内核机制检测“哪些 IO 就绪”,并唤醒对应的协程继续执行。
⸻
🧩 九、与其他模型的关系

⸻
🧠 十、总结口诀

⸻
✅ 一句话总结
事件循环就是协程的“发动机”,
它让单线程的 Python 能并发地执行成千上万个任务,
通过不停地检测“谁准备好了”,在它们之间高效切换。
444

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



