libevent原始碼分析---回顧主要的結構體
阿新 • • 發佈:2019-02-11
以前忘記說明,這裡原始碼分析使用的是libevent庫的1.4.12-stable版本,在2.0以上的版本都是4W+行,過於龐大,網路上看到關於libevent庫中幾個重要的結構體關係圖,很清楚很好,感謝原作者的細緻:
這個結構體的作用這裡就不再累述
其中, struct event_list evsigevents[NSIG]; 成員是一個數組,它的元素 evsigevents[id] 表示註冊到訊號id的事件連結串列.
(虛線部分代表包含關係)
一、tail_queue
關於tail_queue的解釋在上篇文章中很細緻。
二、event
//event提供了函式介面,供Reactor在事件發生時呼叫,以執行相應的事件處理, //通常它會繫結一個有效的控制代碼(ev_fd)做為回撥函式的引數. struct event { //已註冊事件佇列入口 TAILQ_ENTRY (event) ev_next; //已啟用事件佇列入口 TAILQ_ENTRY (event) ev_active_next; //訊號事件佇列入口 不過在以前的分析中可以看到,將來這個佇列中的內容會被新增到ev_active_next佇列中。 TAILQ_ENTRY (event) ev_signal_next; //表示該event在定時器事件最小堆min_heap的索引 unsigned int min_heap_idx; /* for managing timeouts */ //該事件所屬的反應堆例項 struct event_base *ev_base; //對於I/O事件,是繫結的檔案描述符; 對於signal事件,是繫結的訊號. int ev_fd; //表示事件型別: I/O,定時器或者訊號 short ev_events; //事件就緒執行時,將要呼叫ev_callback 的次數,通常為1 short ev_ncalls; //該事件的超時時間,在定時器最小堆min_heap操作中作為節點值進行比較. struct timeval ev_timeout; //該事件的優先順序,越小越優先. int ev_pri; /* smaller numbers are higher priority */ //該事件被啟用時的回撥函式 void (*ev_callback)(int, short, void *arg); //該事件的標記資訊,表示其當前的狀態,即它在哪個連結串列中 int ev_flags; ... //其他成員. };
一個事件是可以插入到多個佇列的,當它與一個反應堆例項(event_base)關聯時,這個事件被插入到反應堆例項下的已註冊事件佇列 event_base -> eventqueue ,當它處於就緒狀態時,會被插入到反應堆例項下的已啟用事件佇列 event_base -> activequeues[id], id = event -> ev_pri .同時,如果此事件是訊號事件,那麼它會被插入到反應堆結構體下的訊號事件結構體下的訊號佇列 event_base -> evsignal_info -> evsigevents[id], id = event -> ev_fd .
需要指出的,每個事件都保持了一個成員 struct event_base *ev_base; ,它表示該事件屬於哪個反應堆例項.
還有一個成員需要注意, short ev_events; ,它表明此事件的事件型別,libevent正是基於此實現對I/O,訊號,定時 3種事件的封裝的.
一般使用情況下,不申請struct event_base.因為在庫中有一個全域性的event_base,所有的事件都可以新增到這個全域性event_base中!!!
三、min_heap
typedef struct min_heap { struct event** p; //p指向一個動態分配的陣列,陣列元素是event指標. unsigned n, a; // n表示目前儲存了多少元素,a表示p指向的記憶體能夠儲存event指標的個數. } min_heap_t;
這個結構體的作用這裡就不再累述
四、evsignal_info
這個結構體是用來管理訊號事件的
struct evsignal_info {
//是否有訊號發生的標記
volatile sig_atomic_t evsignal_caught;
//evsigevents[signo]表示註冊到訊號 signo 的事件連結串列
struct event_list evsigevents[NSIG];
//具體記錄每個訊號觸發的次數,evsigcaught[signo]是記錄訊號signo被觸發的次數
sig_atomic_t evsigcaught[NSIG];
... //其他成員
};
其中, struct event_list evsigevents[NSIG]; 成員是一個數組,它的元素 evsigevents[id] 表示註冊到訊號id的事件連結串列.
還有其他幾個更加重要的結構體
event_base