libevent原始碼深度剖析三

2022-10-10 23:27:17 字數 2263 閱讀 8150

——libevent基本使用場景和事件流程

張亮學習源**該從**入手?我覺得從程式的基本使用場景和**的整體處理流程入手是個不錯的方法,至少從個人的經驗上講,用此方法分析libevent是比較有效的。

基本應用場景也是使用libevnet的基本流程,下面來考慮乙個最簡單的場景,使用livevent設定定時器,應用程式只需要執行下面幾個簡單的步驟即可。

1)首先初始化libevent庫,並儲存返回的指標

struct event_base * base = event_init();

實際上這一步相當於初始化乙個reactor例項;在初始化libevent後,就可以註冊事件了。

2)初始化事件event,設定**函式和關注的事件

evtimer_set(&ev, timer_cb, null);

事實上這等價於呼叫event_set(&ev, -1, 0, timer_cb, null);

event_set的函式原型是:

void event_set(struct event *ev, int fd, short event, void (*cb)(int, short, void *), void *arg)

ev:執行要初始化的event物件;

fd:該event繫結的「控制代碼」,對於訊號事件,它就是關注的訊號;

event:在該fd上關注的事件型別,它可以是ev_read, ev_write, ev_signal;

cb:這是乙個函式指標,當fd上的事件event發生時,呼叫該函式執行處理,它有三個引數,呼叫時由event_base負責傳入,按順序,實際上就是event_set時的fd, event和arg;

arg:傳遞給cb函式指標的引數;

由於定時事件不需要fd,並且定時事件是根據新增時(event_add)的超時值設定的,因此這裡event也不需要設定。

這一步相當於初始化乙個event handler,在libevent中事件型別儲存在event結構體中。

注意:libevent並不會管理event事件集合,這需要應用程式自行管理;

3)設定event從屬的event_base

event_base_set(base, &ev);   

這一步相當於指明event要註冊到哪個event_base例項上;

4)是正式的新增事件的時候了

event_add(&ev, timeout);

基本資訊都已設定完成,只要簡單的呼叫event_add()函式即可完成,其中timeout是定時值;

這一步相當於呼叫reactor::register_handler()函式註冊事件。

5)程式進入無限迴圈,等待就緒事件並執行事件處理

event_base_dispatch(base);

上面例子的程式**如下所示

[cpp]view plain

copy

struct

event ev;  

struct

timeval tv;  

void

time_cb(

intfd, 

short

event, 

void

*argc)  

intmain()  

當應用程式向libevent註冊乙個事件後,libevent內部是怎麼樣進行處理的呢?下面的圖就給出了這一基本流程。

1)    首先應用程式準備並初始化event,設定好事件型別和**函式;這對應於前面第步驟2和3;

2)    向libevent新增該事件event。對於定時事件,libevent使用乙個小根堆管理,key為超時時間;對於signal和i/o事件,libevent將其放入到等待鍊錶(wait list)中,這是乙個雙向鍊錶結構;

3)    程式呼叫event_base_dispatch()系列函式進入無限迴圈,等待事件,以select()函式為例;每次迴圈前libevent會檢查定時事件的最小超時時間tv,根據tv設定select()的最大等待時間,以便於後面及時處理超時事件;

當select()返回後,首先檢查超時事件,然後檢查i/o事件;

libevent將所有的就緒事件,放入到啟用鍊錶中;

然後對啟用鍊錶中的事件,呼叫事件的**函式執行事件處理;

本節介紹了libevent的簡單實用場景,並旋風般的介紹了libevent的事件處理流程,讀者應該對libevent有了基本的印象,下面將

會詳細介紹libevent的事件管理框架(reactor模式中的reactor框架)做詳細的介紹,在此之前會對源**檔案做簡單的分類。

libevent原始碼深度剖析

序幕 張亮上來當然要先誇獎啦,libevent 有幾個顯著的亮點 事件驅動 event driven 高效能 輕量級,專注於網路,不如ace那麼臃腫龐大 源 相當精煉 易讀 跨平台,支援windows linux bsd和mac os 支援多種i o多路復用技術,epoll poll dev pol...

libevent原始碼深度剖析

上來當然要先誇獎啦,libevent 有幾個顯著的亮點 事件驅動 event driven 高效能 輕量級,專注於網路,不如ace那麼臃腫龐大 源 相當精煉 易讀 跨平台,支援windows linux bsd和mac os 支援多種i o多路復用技術,epoll poll dev poll sel...

libevent原始碼深度剖析

序幕 張亮上來當然要先誇獎啦,libevent 有幾個顯著的亮點 事件驅動 event driven 高效能 輕量級,專注於網路,不如ace那麼臃腫龐大 源 相當精煉 易讀 跨平台,支援windows linux bsd和mac os 支援多種i o多路復用技術,epoll poll dev pol...