整個libevent本身就是一個Reactor模式;Reactor是一種事件驅(qū)動機(jī)制,應(yīng)用程序提供相應(yīng)的接口并且注冊到Reactor中,如果相應(yīng)的事件發(fā)生,Reactor將主動調(diào)用應(yīng)用程序的接口。
Reactor框架需要包含幾個組件:事件源,Reactor框架,IO多路復(fù)用機(jī)制,事件處理程序。
事件源:linux上是文件描述符,
IO多路復(fù)用:epoll,select等;程序?qū)㈥P(guān)心的fd以及事件(read,write)注冊到IO多路復(fù)用上(epoll),事件到達(dá)后,epoll發(fā)出通知。
Reactor反應(yīng)器:libevent中就是指event_base結(jié)構(gòu)體。
事件處理程序:對應(yīng)libevent中,就是event結(jié)構(gòu)體。
libevent初始化Reactor:?
struct event_base* reactor = event_base_new();
函數(shù)實現(xiàn)內(nèi)容是 對結(jié)構(gòu)體struct event_base的初始化操作:malloc內(nèi)存,選擇適當(dāng)?shù)腎O多路復(fù)用(此處以epoll為例),調(diào)用IO多路復(fù)用的初始化操作,epoll的初始化操作(epoll_init),調(diào)用epoll_create創(chuàng)建一個RB樹頭節(jié)點。
事件處理程序:event
使用event_new 或者event_assign函數(shù) 獲得一個event,二者的區(qū)別是event_new 內(nèi)部對結(jié)構(gòu)體event進(jìn)行申請空間后再調(diào)用event_assign操作。

event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, short events, void (*callback)(evutil_socket_t, short, void *), void *arg)
函數(shù)event_assign完成的功能是對event結(jié)構(gòu)體的初始化工作

以上對base_event和event 進(jìn)行了初始化相關(guān)操作,二者還沒有進(jìn)行關(guān)聯(lián)起來,調(diào)用event_add函數(shù)是將最終是將此event添加到epoll中的紅黑樹中,event_add--->event_add_internal -----> evmap_io_add---->evsel->add

這個add函數(shù)調(diào)用的是之前關(guān)聯(lián)的epoll中的epoll_nochangelist_add,最終是調(diào)用epoll_ctl將此event添加到之前申請的RB樹中,
epoll_nochangelist_add 調(diào)用epoll_apply_one_change函數(shù),epoll_apply_one_change函數(shù)核心完成功能如下:

至此,將一個event注冊到event_base中了,接下來調(diào)用event_base_loop 函數(shù),等待事件的到來,然后調(diào)用相關(guān)的回調(diào)函數(shù)。
int event_base_loop(struct event_base *base, int flags)
內(nèi)部調(diào)用 evsel->dispatch函數(shù),對應(yīng)epoll中的epoll_dispatch函數(shù),


可以看到loop中最終使用epoll_wait等待事件的到來了,有事件到來時進(jìn)行調(diào)用回調(diào)函數(shù)。
事件返回 的集合,linux下epoll鎖使用的是一個evmap_io列表,記錄給定的fd上可讀或者可寫的所有事件,以及每個事件的數(shù)量。
res返回后,調(diào)用evmap_io_active??激活在event_base上等待給定fd的一組事件。
event_base_loop 中 res = evsel->dispatch(base, tv_p); 返回激活的數(shù)量,激活事件存放到了event_base結(jié)構(gòu)體中的activequeues隊列中,

最后循環(huán)隊列執(zhí)行回調(diào)函數(shù)。
