- 事件多路分发机制(event demultiplexer),即epoll、kqueue、select等
- 事件源,在指定的文件描述符上注册关心的事件,如I/O读写、定时、信号事件
- 事件处理器(event handler),事件触发时被调用
- 反应器(reactor),事件管理接口,注册事件后进入循环,事件就绪时调用事件处理函数
libevent中主要的几个接口:
- event_init:初始化libevent库,生成event_base实例
- event_set:初始化事件event,设置回调函数和关注的事件
- event_base_set:设置event从属的event_base,即指明event要注册到哪个event_base上
- event_add:正式添加事件
- event_base_dispatch:程序进入无限循环,等待就绪事件
以下是上面各个函数的具体实现(基于libevent-2.0.20-stable版本)。
event_init函数:调用event_base_new_with_config,该函数进行事件多路分发机制选择。epoll、kqueue、select等多种事件多路分发机制被存放在eventops数组中,从该数组下标0开始选择,将选好的事件多路分发机制存放在evsel字段中。之后调用evsel->init,该接口函数最终调用对应事件多路分发机制的初始化函数,如epoll对应的是epoll_create。
event_set函数:调用event_assign,event_assign函数中,填充event结构中的文件描述符、事件类型、事件处理函数等字段。
event_base_set函数:简单地设定event结构中的ev_base字段为指定值。
event_add函数:调用event_add_internal,该函数中,根据不同的事件类型,调用不同函数处理,对于I/O,调用evmap_io_add;对于signal,调用evmap_signal_add。之后调用event_queue_insert,将事件加入激活事件队列。
在evmap_io_add和evmap_signal_add中,均会调用evsel->add,其作用就是调用某个具体事件多路分发机制的接口函数,完成事件添加。例如对应于epoll的add函数就是epoll_nochangelist_add,该函数调用epoll_apply_one_change,epoll_apply_one_change调用epoll_ctl进行事件注册。
event_base_dispatch函数:调用event_base_loop,该函数调用evsel->dispatch,即事件多路分发机制注册的dispatch函数,对应于epoll就是epoll_dispatch,epoll_dispatch调用epoll_wait,调用event_set函数时设定了监听的文件描述符,epoll_wait在此文件描述符上等待I/O事件发生。
Have fun!