Eventlet Hub
Eventlet 实现了多种类型的 Hub,在实际使用时,Eventlet 会根据系统运行环境选择最适合的一种实现方式。Eventlet 目前支持以下4种 Hub。
- epolls - 需要在 Linux 环境下,Python 2.6 或者
python-poll包。它是处理速度最快的纯 Python Hub。 - poll - 需要在支持 poll 的平台上选择使用
- selects - 效率最低,适合任何平台。
- pyevent - 基于 libevent,效率最高。因为它不支持线程,所以默认不生效。
Hub 是 greenthread 执行IO任务的调度中心。greenthread 被创建出来后,被添加到 Hub 的 Timer 待调度列表中。在 Hub 的 MAINLOOP 检测到某 greenthread 有IO任务就绪时,切换到该 greenthread 执行其 function 方法。
|
|
运行结果:执行sleep()后,立即打印 Hello Eventlet.
eventlet.spawn(test) 创建了一个 greenthread,执行任务 test。
|
|
hubs.get_hub()获得线程内全局单例 hub 对象,使用hub.greenlet作为父协程创建 greenthread g, hub.greenlet=greenlet.greenlet(self.run)。hub.schedule_call_global()方法在 Hub 中注册func方法,g.switch切换到 greenthread g 的 main()方法执行。
|
|
真正触发切换到 greenthread g 执行的操作是 eventlet.sleep(0) 。
|
|
hub.switch() 执行 hub 的 switch() 方法。
|
|
self.greenlet.switch() 切换到 self.greenlet, 即MAINLOOP 执行,MAINLOOP 即是 hub.run() 方法。
|
|
先捡重点的看,prepare_timers()和 fire_timers()。
|
|
prepare_timers() 将 self.next_timers 中没有 called 的 greenthread 放入 self.timers。fire_timers() 判断 self.times 中的 greenthread 到时间执行后,通过 timer() 的方式执行。
|
|
cb 就是 eventlet.spawn 中的 g.switch。那么执行 cb(*args, **kw) 就是切换到 g 中去执行。
|
|
切换到 g 后,执行 main() 函数,此时终于执行到了真正的 function 方法。