Setting up a default event_base
The event_base_new() function allocates and returns a new event base with the default settings. It examines the environment variables and returns a pointer to a new event_base.
If there is an error, it returns NULL.
When choosing among methods, it picks the fastest method that the OS supports.
event_base_new()創建默認event_base,他檢測環境變量並且返回一個指向新的event_base的指針。
當調用方法時,選擇操作系統支持的做快速的方法。
Interface
struct event_base *event_base_new(void);
Setting up a complicated event_base
If you want more control over what kind of event_base you get, you need to use an event_config. An event_config is an opaque structure that holds information about your preferences for an event_base. When you want an event_base, you pass the event_config to event_base_new_with_config().
想要創建指定類型的event_base,需要使用event_config,event_config是不透明的結構體,保存了您創建event_base時需要的特性。
用戶調用event_base_new_with_config創建特殊類型的event_base
Interface
struct event_config *event_config_new(void); struct event_base *event_base_new_with_config(const struct event_config *cfg); void event_config_free(struct event_config *cfg);
To allocate an event_base with these functions, you call event_config_new() to allocate a new event_config. Then, you call other functions on the event_config to tell it about your needs. Finally, you call event_base_new_with_config() to get a new event_base. When you are done, you can free the event_config with event_config_free().
為了創造一個有特定功能的event_base,你需要調用event_config_new()創建event_config,只后調用event_base_new_with_config(),之后調用event_config_free釋放。
Interface:
int event_config_avoid_method(struct event_config *cfg, const char *method); enum event_method_feature { EV_FEATURE_ET = 0x01, EV_FEATURE_O1 = 0x02, EV_FEATURE_FDS = 0x04, }; int event_config_require_features(struct event_config *cfg, enum event_method_feature feature); enum event_base_config_flag { EVENT_BASE_FLAG_NOLOCK = 0x01, EVENT_BASE_FLAG_IGNORE_ENV = 0x02, EVENT_BASE_FLAG_STARTUP_IOCP = 0x04, EVENT_BASE_FLAG_NO_CACHE_TIME = 0x08, EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST = 0x10, EVENT_BASE_FLAG_PRECISE_TIMER = 0x20 }; int event_config_set_flag(struct event_config *cfg, enum event_base_config_flag flag);
Calling event_config_avoid_method tells Libevent to avoid a specific available backend by name. Calling event_config_require_feature() tells Libevent not to use any backend that cannot supply all of a set of features. Calling event_config_set_flag() tells Libevent to set one or more of the run-time flags below when constructing the event base.
event_config_avoid_method 可以規避一些函數,通過傳入函數的名字,event_config_require_feature告訴libevent不要使用不支持指定特性的功能。
event_config_set_flag告訴libevent設置一個或多個運行時標記,當你創建event base時。
特性的標記位如下:
EV_FEATURE_ET:要求后端方法支持edge-triggered IO
EV_FEATURE_O1:要求添加或者刪除,或者激活某個事件的事件復雜度為O(1)
EV_FEATURE_FDS:要求后端方法支持任意類型的文件描述符,不僅僅是socket
EVENT_BASE_FLAG_NOLOCK:不為event_base設置鎖,可以省去event_base加鎖和釋放鎖的時間,但是對於多線程操作,並不安全。
EVENT_BASE_FLAG_IGNORE_ENV:當調用后端的方法時並不檢查EVENT_*環境變量,用這個選項時注意,會導致程序和Libevent庫之間調試麻煩
EVENT_BASE_FLAG_STARTUP_IOCP:僅對windows有效,通知Libevent在啟動的時候就是用必要的IOCP 派發邏輯,而不是在需要時才用IOCP派發邏輯。
EVENT_BASE_FLAG_NO_CACHE_TIME:每次超時回調函數調用后檢測當前時間,而不是准備調用超時回調函數前檢測。
EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST:通知libevent,如果后台使用epoll模型,使用changelist是安全的,
epoll-changelist 能夠避免在兩次派發之間如果同一個fd的狀態有改變,多次不必要的系統調用。換句話說在派發消息中間,如果同一個fd多次改動,那么最終只調用一次系統
調用。如果后台不是epoll模型,那么這個選項是沒什么影響。同樣可以設置EVENT_EPOLL_USE_CHANGELIST 環境變量達到這個目的。
EVENT_BASE_FLAG_PRECISE_TIMER:libevent默認使用快速的定時器機制,設置這個選項后,如果有一個慢速的但是定時器精度高的機制,那么就會切換到這個機制。
如果沒有這個機制,那么這個選項沒什么影響。
下面幾個例子說明了這些api用法
static void test_base_features(void *arg) { struct event_base *base = NULL; struct event_config *cfg = NULL; //創建一個event_config cfg = event_config_new(); //設置在epoll模型情況下支持et模式 tt_assert(0 == event_config_require_features(cfg, EV_FEATURE_ET)); //創建event_base base = event_base_new_with_config(cfg); if (base) { tt_int_op(EV_FEATURE_ET, ==, event_base_get_features(base) & EV_FEATURE_ET); } else { base = event_base_new(); tt_int_op(0, ==, event_base_get_features(base) & EV_FEATURE_ET); } end: //結束時要釋放base和config if (base) event_base_free(base); if (cfg) event_config_free(cfg); }
下面這個是測試方法的
static void test_methods(void *ptr) { //獲取event_base支持的方法 const char **methods = event_get_supported_methods(); struct event_config *cfg = NULL; struct event_base *base = NULL; const char *backend; int n_methods = 0; tt_assert(methods); backend = methods[0]; while (*methods != NULL) { TT_BLATHER(("Support method: %s", *methods)); ++methods; ++n_methods; } cfg = event_config_new(); assert(cfg != NULL); //event_base屏蔽backend的方法 tt_int_op(event_config_avoid_method(cfg, backend), ==, 0); //並且設置了忽略ENV環境變量的選項 event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV); //創建event_base base = event_base_new_with_config(cfg); if (n_methods > 1) { tt_assert(base); tt_str_op(backend, !=, event_base_get_method(base)); } else { tt_assert(base == NULL); } end: if (base) event_base_free(base); if (cfg) event_config_free(cfg); }
我的公眾號:

