1.使用libevent库
源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了,而后去看底层相应的源码,这样比较有条理,自上向下掌握。下面用libevent库写个程序,每隔1秒输出一行信息。
2.event, event_base
通过第1步,下面开始看上面程序中的每一部分的源码。首先是两个核心结构体event和event_base
3.event_init()
下面开始进入libevent的运行流程了,首先调用是event_init()初始化event_base
从event_init()源码中,看到event_init()调用了event_base_new()函数,这个函数才是完成event_base初始化的主要函数。event_base_new()首先在堆上分配内存来存储event_base结构,而后就是去初始化各类成员。
值得注意的是,libevent用一个全局数组eventops存储系统支持的各类I/O多路复用机制,而后在event_base_new()中去遍历该数组,从中选择第1个I/O多路复用机制。
由于event是能够设置优先级的,活跃事件链表中,优先级值越小,越优先。因此在event_base_new()函数内又调用了event_base_priority_init()函数初始化event_base的activequeues和nactivequeues成员。
4.event_set()、event_base_set()
初始化完event_base后,下面要初始化event,经过调用event_set()实现;而后调用event_base_set()设置event所属的event_base
从源码能够看到,这步主要经过输入参数初始化event结构体,设置其回调函数,设置其在小根堆中索引,设置event的优先级。html
5.event_add()
接下来就是将event注册到event_base的事件链表中了。
从源码分析出,
这个函数主要完成了下面几件事:
1.将event注册到event_base的I/O多路复用要监听的事件链表中
2.将event注册到event_base的已注册事件链表中
3.若是传入了超时时间,则删除旧的超时时间,从新设置,并将event添加到event_base的小根堆中;
若是没有传入超时时间,则不会添加到小根堆中。
该函数内添加到I/O多路复用监听事件链表、已注册事件链表、小根堆中都是经过event_queue_insert()完成的,相应的删除工做都是经过event_queue_remove()完成的。
6. event_base_dispatch()
该函数只是作了调用event_base_loop()这一个动做,因此工做实际是在函数event_base_loop()内完成的。在该函数内部调用了eventop.dispatch()监听事件。并调用event_process_active()处理活跃事件链表中的事件,调用相应的回调函数。