1. 程式人生 > >libevent庫的外部和內部實現

libevent庫的外部和內部實現

一、從大的方面來講libevent的實現就是:

1、往libevent庫裡註冊事件(I/O事件、signal事件、定時器事件)

2、啟動事件迴圈

3、通過I/O複用(select/poll/epoll)來將有就緒事件通知給系統

4、根據相應事件呼叫相應的函式

二、從細節方面來講它就是(內部實現):

1、首先應用程式準備並初始化event,設定好事件型別和回撥函式;

2、向libevent新增事件event。對於定時事件,libevent使用一個小根堆管理,對於Signal和I/O事件,libevent將其放入到等待連結串列中,這是一個雙向連結串列結構

3、程式呼叫event_base_dispatch()系列函式進入無限迴圈,等待事件,以select()函式為例;每次迴圈前libevent會檢查定時事件的最小超時時間tv,根據tv設定select()的最大等待時間,以便於後面及時處理超時事件;當select()返回後,首先檢查超時事件,然後檢查I/O事件,Libevent將所有的就緒事件放入到啟用連結串列中;然後對連結串列中的事件呼叫事件的回撥函式執行事件處理;

通俗一點講就是,當事件進入libevent庫之後她們會在自己的佇列中排著,每次當有事件event轉變為就緒狀態時,libevent就會把它移入到active event list[priority]中,其中priority是event的優先順序,接著,libevent會根據自己的排程策略選擇就緒事件,呼叫其cb_callback()函式執行處理;並根據就緒事件的控制代碼和事件型別填充cb_callback函式的引數。直到這三個佇列上都沒有事件之後libevent就退出了,這是libevent退出的其中一種情況,另外一種就是呼叫函式讓libevent退出

三、考點:epoll_wait利用超時時間做定時器的原理

假設我們定的超時時間是5分鐘,那麼epoll_waiit在5分鐘的時候肯定會返回一次,如果提前返回也沒有關係,提前返回肯定是I/O上有事件發生了,那就呼叫I/O去處理,下一次呼叫epoll_wait的時候還要檢查計算時間,返回的時間和超時時間做一次差值計算,然後讓它阻塞這個差值時間這麼久再返回,返回的時候再次去檢視時間,如果正好是這個超時時間的時間點就呼叫timer函式,返回超時。