chromium libevent

chromium android/linux/mac 中用libevent來做爲底層io檢測,即MessagePumpLibevent來實現io線程循環。


1 libevent 簡介(百度百科)

    官網: http://libevent.org/

   libevent是一個事件觸發的網絡庫,適用於windows、linux、bsd等多種平臺,內部使用select、epoll、kqueue等系統調用管理事件機制。根據libevent官方網站上公佈的數據統計,似乎也有着非凡的性能。libevent支持多線程編程,每個事件需要關聯到自己的event_base。libevent包括事件管理、緩存管理、DNS、HTTP、緩存事件幾大部分。事件管理包括各種IO(socket)、定時器、信號等事件;緩存管理是指evbuffer功能;DNS是libevent提供的一個異步DNS查詢功能;HTTP是libevent的一個輕量級http實現,包括服務器和客戶端。libevent也支持ssl,這對於有安全需求的網絡程序非常的重要,但是其支持不是很完善,比如http server的實現就不支持ssl。


2. libevent 簡單使用

    http://www.open-open.com/lib/view/open1386510630330.html

   1> timer事件

<span style="font-size:12px;">#include <stdio.h>  
#include <iostream>  
  
// libevent頭文件  
#include <event.h>  
using namespace std;  
  
// 定時事件回調函數  
void onTime(int sock, short event, void *arg)  
{  
    cout << "Game Over!" << endl;  
  
    struct timeval tv;  
    tv.tv_sec = 1;  
    tv.tv_usec = 0;  
    // 重新添加定時事件(定時事件觸發後默認自動刪除)  
    event_add((struct event*)arg, &tv);  
}  
  
int main()  
{  
    // 初始化  
    event_init();  
  
    struct event evTime;  
    // 設置定時事件  
    evtimer_set(&evTime, onTime, &evTime);  
  
    struct timeval tv;  
    tv.tv_sec = 1;  
    tv.tv_usec = 0;  
    // 添加定時事件  
    event_add(&evTime, &tv);  
  
    // 事件循環  
    event_dispatch();  
  
    return 0;  
}  </span>
    2> io端口監聽

    僞代碼

    

<span style="font-size:12px;">int main(void)
{
    // 初始化base  
    base = event_base_new();  
      
    struct event evListen;  
    // 設置事件  
    event_set(&evListen, fd, EV_READ|EV_PERSIST, CallbackFunction, NULL);  
    // 設置爲base事件  
    event_base_set(base, &evListen);  
    // 添加事件  
    event_add(&evListen, NULL);  
      
    // 事件循環  
    event_base_dispatch(base);  
  
    return 0;  
}  </span>

3. libevent 事件循環

    上述例子中,調用event_base_dispatch函數就進入了libevent事件循環,但真正的循環函數是event_base_loop。event_base_dispatch調用event_base_loop,其中flags參數爲0.

      int event_base_loop(struct event_base *baseint flags);

    該函數可以工作在3中模式下,有flags來區分不同的模式。libevent中定義了兩個宏來區別循環模式:

   #define EVLOOP_ONCE                    0x01           
   #define EVLOOP_NONBLOCK         0x02

默認情況下,event_base_loop()函數運行event_base直到其中沒有已經註冊的事件爲止。執行循環的時候,函數重複地檢查(多種 I/O多路複用技術: epoll、poll、dev/poll、select 和kqueue )是否有任何已經註冊的事件被觸發(比如說,讀事件的文件描述符已經就緒,可以讀取了;或者超時事件的超時時間即將到達)。如果有事件被觸發,函數標記被觸發的事件爲“激活的”,並且執行這些事件。

如果設置了EVLOOP_ONCE,循環將等待某些事件成爲激活的,執行激活的事件直到沒有更多的事件可以執行,然會返回。

如果設置了EVLOOP_NONBLOCK,循環不會等待事件被觸發:循環將僅僅檢測是否有事件已經就緒,可以立即觸發,如果有,則執行事件的回調。


chromium中使用了`EVLOOP_ONCE和EVLOOP_NONBLOCK


4. 多路複用封裝eventop

struct eventop {
    const char *name;
    void *(*init)(struct event_base *); // 初始化
    int (*add)(void *, struct event *); // 註冊事件
    int (*del)(void *, struct event *); // 刪除事件
    int (*dispatch)(struct event_base *, void *, struct timeval *); // 事件分發
    void (*dealloc)(struct event_base *, void *); // 註銷,釋放資源
    /* set if we need to reinitialize the event base */
    int need_reinit;

};

epoll、poll、dev/poll、select 和kqueue 都會實現這5個接口。




資料:

http://blog.csdn.net/sparkliang/article/details/4957667

http://www.cppblog.com/mysileng/archive/2013/02/04/197719.html

     




發佈了66 篇原創文章 · 獲贊 16 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章