1.使用libevent庫
源碼那麼多,該怎麼分析從哪分析呢?一個好的方法就是先用起來,會用了,而後去看底層相應的源碼,這樣比較有條理,自上向下掌握。下面用libevent庫寫個程序,每隔1秒輸出一行信息。
2.event, event_base
通過第1步,下面開始看上面程序中的每一部分的源碼。首先是兩個核心結構體event和event_base
3.event_init()
下面開始進入libevent的運行流程了,首先調用是event_init()初始化event_base
從event_init()源碼中,看到event_init()調用了event_base_new()函數,這個函數纔是完成event_base初始化的主要函數。event_base_new()首先在堆上分配內存來存儲event_base結構,而後就是去初始化各類成員。
值得注意的是,libevent用一個全局數組eventops存儲系統支持的各類I/O多路複用機制,而後在event_base_new()中去遍歷該數組,從中選擇第1個I/O多路複用機制。
由於event是能夠設置優先級的,活躍事件鏈表中,優先級值越小,越優先。因此在event_base_new()函數內又調用了event_base_priority_init()函數初始化event_base的activequeues和nactivequeues成員。
4.event_set()、event_base_set()
初始化完event_base後,下面要初始化event,經過調用event_set()實現;而後調用event_base_set()設置event所屬的event_base
從源碼能夠看到,這步主要經過輸入參數初始化event結構體,設置其回調函數,設置其在小根堆中索引,設置event的優先級。html
5.event_add()
接下來就是將event註冊到event_base的事件鏈表中了。
從源碼分析出,
這個函數主要完成了下面幾件事:
1.將event註冊到event_base的I/O多路複用要監聽的事件鏈表中
2.將event註冊到event_base的已註冊事件鏈表中
3.若是傳入了超時時間,則刪除舊的超時時間,從新設置,並將event添加到event_base的小根堆中;
若是沒有傳入超時時間,則不會添加到小根堆中。
該函數內添加到I/O多路複用監聽事件鏈表、已註冊事件鏈表、小根堆中都是經過event_queue_insert()完成的,相應的刪除工做都是經過event_queue_remove()完成的。
6. event_base_dispatch()
該函數只是作了調用event_base_loop()這一個動做,因此工做實際是在函數event_base_loop()內完成的。在該函數內部調用了eventop.dispatch()監聽事件。並調用event_process_active()處理活躍事件鏈表中的事件,調用相應的回調函數。