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 方法。