libevent是一個事件觸發的網絡庫,適用於windows、linux、bsd等多種平臺,內部使用select、epoll、kqueue等系統調用管理事件機制。著名分佈式緩存軟件memcached也是libevent based,並且libevent在使用上能夠作到跨平臺,並且根據libevent官方網站上公佈的數據統計,彷佛也有着非凡的性能。php
例如 : 客戶端鏈接到服務端屬於一個鏈接的事件,當這個事件觸發的時候就會去處理。linux
event_base是event的一個集合,主要是用來管理和實現事件的監聽循環。通常狀況下一個線程一個event_base,多個線程的狀況下須要開多個event_base。windows
建立event_base 緩存
struct event_base *event_base_new(void);
銷燬event_base網絡
void event_base_free(struct event_base *base);
初始化event_basesocket
int event_reinit(struct event_base *base);
銷燬event_base分佈式
void event_base_free(struct event_base *base);
IO多路複用模型中 (IO模型文章),有多種方法能夠供咱們選擇,可是這些模型是在不一樣的平臺下面的: select poll epoll kqueue devpoll evport win32memcached
當咱們建立一個event_base的時候,libevent會自動爲咱們選擇最快的IO多路複用模型,Linux下通常會用epoll模型。函數
獲取io多路複用模型名稱oop
const char *event_base_get_method(const struct event_base *base);
事件循環監聽event_loop event_base是須要監聽的event事件集合,須要循環被監聽
監聽函數
int event_base_dispatch(struct event_base *base);
int event_base_loop(struct event_base *base, int flags);
event事件
even_base中的基本單元,事件。
例如 socket進行網絡開發的時候,都會使用accept這個方法來阻塞監聽是否有客戶端socket鏈接上來,若是客戶端鏈接上來,則會建立一個線程用於服務端與客戶端進行數據的交互操做,而服務端會繼續阻塞等待下一個客戶端socket鏈接上來,客戶端鏈接到服務端實際就是一種事件。
建立event
struct event *event_new(struct event_base *base, evutil_socket_t fd,short what, event_callback_fn cb,void *arg);
參數:
1. base:即event_base
2. fd:文件描述符。
3. what:event關心的各類條件。
4. cb:回調函數。
5. arg:用戶自定義的數據,能夠傳遞到回調函數中去。
libevent是基於事件的,也就是說只有在事件到來的這種條件下才會觸發當前的事件。例如:
1. fd文件描述符已準備好可寫或者可讀
2. fd立刻就準備好可寫和可讀。
3. 超時的狀況 timeout
4. 信號中斷
5. 用戶觸發的事件
void event_free(struct event *event);
int event_add(struct event *ev, const struct timeval *tv);
// base --- event_base // signum --- 信號,例如 SIGHUP // callback --- 信號出現時調用的回調函數 // arg --- 用戶自定義數據 evsignal_new(base, signum, cb, arg) //將信號 event 註冊到 event_base evsignal_add(ev, tv) // 清理信號 event evsignal_del(ev)
1. 每個事件event都須要經過event_new初始化生成。event_new生成的事件是在堆上分配的內存。
2. 當一個事件經過event_add被註冊到event_base上的時候,這個事件處於pending(等待狀態),當只有有事件進來的時候,event纔會被激活active狀態,相關的回調函數就會被調用。
3. persistent 若是event_new中的what參數選擇了EV_PERSIST,則是持久的類型。持久的類型調用玩回調函數後,會繼續轉爲pending狀態,就會繼續等待事件進來。大部分狀況下會選擇持久類型的事件。
3. 而非持久的類型的事件,調用玩一次以後,就會變成初始化的狀態。這個時候須要調用event_add 繼續將事件註冊到event_base上以後才能使用。