gevent之所以性能好,最主要就得益于对libev的封装,这里就来看看这部分具体的实现。。。
稍微看一下libev的用法就知道,libev将各种事件都定义为了watcher,这里包括了定时,io等等。。
在gevent主要就是对libev的loop以及watcher进行了封装。。这部分采用的是cython来写的。。
通过以前看的gevent的代码可以知道,所有建立的协程都有一个共同的parent协程,也就是hub协程,他有一个loop对象,其实就可以理解为gevnet通过hub协程来管理整个loop的运行。。。
loop是采用cython来编写的,代码在core.pyx里面。。。
先来看看它的一些属性的定义:
cdef libev.ev_loop* _ptr #libev的loop的引用
cdef public object error_handler
cdef libev.ev_prepare _prepare #这个prepare事件,每次在loop之前,都会调用它的回调
cdef public list _callbacks #当前loop对象上面挂起的所有回调的链表
cdef libev.ev_timer _timer0 #一个超时为0的timer,用于让loop立即返回
对于这几个属性,上面的注释应该很清楚了。。。嗯,这里要感叹一下,用cython来写python的扩展还真的很方便。。。
好了,这里来看看构造函数吧:
#构造函数
def __init__(self, object flags=None, object default=None, size_t ptr=0):
cdef unsigned int c_flags
cdef object old_handler = None
#这个是注册每次event loop 之前的回调,每次loop开始之前,就会执行这里
#其实最终调用的时_run_callbacks方法
libev.ev_prepare_init(&self._prepare, <void*>gevent_run_callbacks)
#ifdef _WIN32
libev.ev_timer_init(&self._periodic_signal_checker, <void*>gevent_periodic_signal_check, 0.3, 0.3)
#endif
#注册这个timer的回调,这个回调其实什么都不做,主要的目的就是让event loop的循环立即退出,去处理回调
libev.ev_timer_init(&self._timer0, <void*>gevent_noop, 0.0, 0.0)
if ptr:
self._ptr = <libev.ev_loop*>ptr
else:
c_flags = _flags_to_int(flags)
_check_flags(c_flags)
c_flags |= libev.EVFLAG_NOENV
if default is None:
default = True
if _default_loop_destroyed:
default = False
if default:
self._ptr = libev.gevent_ev_default_loop(c_flags)
if not self._ptr:
raise SystemError("ev_default_loop(%s) failed" % (c_flags, ))
#ifdef _WIN32
libev.ev_timer_start(self._ptr, &self._periodic_signal_checker)
libev.ev_unref(self._ptr)
#endif
else: #创建loop的引用,一般情况下都是在这里创建的
self._ptr = libev.ev_loop_new(c_flags)
if not