Libevent應用 (一) 建立event_base
event_base算是Libevent最基礎、最重要的物件,因為修改配置、新增事件等,基本都需要將它作為引數傳遞進去。
1.1建立預設的event_base
這個物件通過event_base_new建立:
struct event_base *event_base_new(void);
event_base_new()函式分配並且返回一個新的具有預設設定的event_base。函式會檢測環境變數,返回一個到event_base的指標。如果發生錯誤,則返回NULL。選擇各種方法時,函式會選擇OS支援的最快方法。
使用完event_base之後,使用event_base_free()進行釋放。
void event_base_free(struct event_base *base);
注意:這個函式不會釋放當前與event_base關聯的任何事件,或者關閉他們的套接字,或者釋放任何指標。
編譯的時候需要加上-levent
1.2 檢查後端的方法
有時候需要檢查event_base支援哪些特徵,或者當前使用哪種方法。
const char **event_get_supported_methods(void); const char *event_get_version();
event_get_supported_methods()函式返回一個指標,指向libevent支援的方法名字陣列。這個陣列的最後一個元素是NULL。
int main(void) { int i = 0; const char **methods = event_get_supported_methods(); printf("Starting Libevent %s. Available methods are:\n", event_get_version()); while(methods[i] != NULL) { printf("%s\n", methods[i++]); } }
1.3 建立複雜的event_base
要對取得什麼型別的event_base有更多的控制,就需要使用event_config。event_config是一個容納event_base配置資訊的不透明結構體。需要event_base時,將event_config傳遞給event_base_new_with_config()。
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);
要使用這些函式分配event_base,先呼叫event_config_new()分配一個event_config。然後,對event_config呼叫其它函式,設定所需要的event_base特徵。最後,呼叫event_base_new_with_config()獲取新的event_base。完成工作後,使用event_config_free()釋放event_config。
1.3.1 禁用特定後端
呼叫event_config_avoid_method()可以通過名字讓libevent避免使用特定的可用後端。成功時返回0,失敗時返回-1。
int event_config_avoid_method(struct event_config *cfg, const char *method); const char* method;//指定特定的後端,例如"select" "poll" "epoll"
1.3.2 設定特徵
呼叫event_config_require_feature()讓libevent不使用不能提供所有指定特徵的後端。成功時返回0,失敗時返回-1。
int event_config_require_features(struct event_config *cfg, enum event_method_feature feature); enum event_method_feature { EV_FEATURE_ET = 0x01, //要求支援邊沿觸發的後端 EV_FEATURE_O1 = 0x02, //要求新增、刪除單個事件,或者確定哪個事件啟用的操作是O(1)複雜度的後端 EV_FEATURE_FDS = 0x04, //要求支援任意檔案描述符,而不僅僅是套接字的後端 };
注意:
設定event_config,請求OS不能提供的後端是很容易的。
比如說,對於libevent 2.0.1-alpha,在Windows中是沒有O(1)後端的;
在Linux中也沒有同時提供EV_FEATURE_FDS和EV_FEATURE_O1特徵的後端。
如果建立了libevent不能滿足的配置,event_base_new_with_config()會返回NULL。
1.3.3 設定標誌
呼叫event_config_set_flag()讓libevent在建立event_base時設定一個或者多個將在下面介紹的執行時標誌。成功時返回0,失敗時返回-1。
int event_config_set_flag(struct event_config *cfg, enum event_base_config_flag flag); 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 };
EVENT_BASE_FLAG_NOLOCK://不要為event_base分配鎖。設定這個選項可以為event_base節省一點用於鎖定和解鎖的時間,但是讓在多個執行緒中訪問event_base成為不安全的。 EVENT_BASE_FLAG_IGNORE_ENV://選擇使用的後端時,不要檢測EVENT_*環境變數。使用這個標誌需要三思:這會讓使用者更難除錯你的程式與libevent的互動。 EVENT_BASE_FLAG_STARTUP_IOCP://僅用於Windows,讓libevent在啟動時就啟用任何必需的IOCP分發邏輯,而不是按需啟用。 EVENT_BASE_FLAG_NO_CACHE_TIME://不快取時間,在每個超時事件之後重新讀取系統時間. EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST://告訴libevent,如果決定使用epoll後端,可以安全地使用更快的基於changelist的後端。epoll-changelist後端可以在後端的分發函式呼叫之間,同樣的fd多次修改其狀態的情況下,避免不必要的系統呼叫。但是如果傳遞任何使用dup()或者其變體克隆的fd給libevent,epoll-changelist後端會觸發一個核心bug,導致不正確的結果。在不使用epoll後端的情況下,這個標誌是沒有效果的。也可以通過設定EVENT_EPOLL_USE_CHANGELIST環境變數來開啟epoll-changelist選項。
1.3.4 event_base優先順序
libevent支援為事件設定多個優先順序。然而,event_base預設只支援單個優先順序。可以呼叫event_base_priority_init()設定event_base的優先順序數目。
int event_base_priority_init(struct event_base *base, int n_priorities);
成功時這個函式返回0,失敗時返回-1。base是要修改的event_base,n_priorities是要支援的優先順序數目,這個數目至少是1。每個新的事件可用的優先順序將從0(最高)到n_priorities-1(最低)。
常量EVENT_MAX_PRIORITIES表示n_priorities的上限。呼叫這個函式時為n_priorities給出更大的值是錯誤的。
注意:
必須在任何事件啟用之前呼叫這個函式,最好在建立event_base後立刻呼叫。
1.3.5 定製event_base程式碼
struct event_config *cfg; struct event_base *base; cfg = event_config_new(); event_config_avoid_method(cfg, "select"); //避免使用低效率select event_config_require_features(cfg, EV_FEATURE_ET); //使用具有邊沿觸發型別的後端 event_config_set_flag(cfg, EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST); base = event_base_new_with_config(cfg); event_config_free(cfg); event_base_priority_init(base, 3); //設定優先順序 event_base_free(base);
1.3.6 檢查後端和特徵
event_base_get_method()返回event_base正在使用的方法。event_base_get_features()返回event_base支援的特徵的位元掩碼。
const char *event_base_get_method(const struct event_base *base); enum event_method_feature event_base_get_features(const struct event_base *base);
示例程式碼如下:
int main(void) { struct event_base *base; enum event_method_feature f; base = event_base_new(); if (!base) { puts("Couldn't get an event_base!"); } else { printf("Using Libevent with backend method %s.\n", event_base_get_method(base)); f = event_base_get_features(base); if ((f & EV_FEATURE_ET)) printf(" Edge-triggered events are supported.\n"); if ((f & EV_FEATURE_O1)) printf(" O(1) event notification is supported.\n"); if ((f & EV_FEATURE_FDS)) printf(" All FD types are supported.\n"); puts(""); } }
相關文章
- libevent之event_base
- 【Linux系統程式設計】libevent庫event_base結構體Linux程式設計結構體
- Libevent應用 (零) Libevent簡單介紹與安裝
- Libevent應用 (二) 與事件一起工作事件
- Libevent應用 (三) 資料緩衝
- Libevent應用(六)從bufferevent中取出evbuffer
- Libevent應用 (四) 輔助型別和函式型別函式
- Libevent應用 (五) 連線監聽器,接收tcp連線TCP
- 嘗試使用Knative建立一個應用
- 用 Docker 建立 serverless 應用DockerServer
- 用 Vue 建立一個簡單的 electron 桌面應用Vue
- 如何用node.js建立一個應用Node.js
- Git 學習以及建立第一個應用Git
- 第一章 建立部落格應用
- 玩轉 PHP 網路程式設計全套之 libevent 框架多人聊天應用PHP程式設計框架
- 使用 SAP BTP 建立一個 Spring Boot Java 應用Spring BootJava
- libevent之event
- libevent之bufferevents
- libevent之evbuffer
- libevent之evconnlistener
- 2 – 建立 Django 部落格應用Django
- 如何用TypeScript來建立一個簡單的Web應用TypeScriptWeb
- SpringBoot2.x入門:快速建立一個SpringBoot應用Spring Boot
- Flutter 應用程式建立一個擴充套件皮膚列表Flutter套件
- Maven建立Web應用程式專案MavenWeb
- 2.3.5 隱式建立的應用程式
- 使用Spring AI + Redis 建立RAG應用SpringAIRedis
- Nodejs教程19:WebSocket之一:使用Socket.io建立WebSocket應用NodeJSWeb
- 使用SAP CDS view快速建立一個Fiori應用,管理Service OrderView
- 複製Monkeytype:如何建立一個高效的打字練習應用
- libevent入門介紹
- 為 Node.js 應用建立一個更安全的沙箱環境Node.js
- 宜信開源|手把手教你建立第一個Davinci應用
- RIS,建立 React 應用的新選擇React
- Flutter應用Windows安裝包建立教程FlutterWindows
- Django建立app應用和admin模組DjangoAPP
- Visual Studio 2005 如何建立“Web 應用程式”Web
- 使用 nuxi add 快速建立 Nuxt 應用元件UX元件