libevent 使用流程
使用流程
- 創建一個事件處理框架
- 創建一個事件
- 事件添加到處理框架
- 開始事件循環
- 釋放資源
事件處理框架 - event_base
-
使用libevent函數之前需要分配一個或者多個event_base結構體. 每個event_base結構體有一個事件集合,可以檢測以確定哪個事件是激活的.
- 相當於epoll紅黑樹的樹根
- 底座
- 抽象層,完成對event_base的封裝
- 每個event_base都有一種用於檢測那種事件已經就緒的"方法",或者說后端
-
具體操作
- 創建event_base
struct event_base* event_base_new(void);
- 失敗返回NULL
- 釋放event_base
event_base_free(struct event_base* base);
- 循環監聽base對應的事件, 等待條件滿足
event_base_dispatch(struct event_base* base);
- 創建event_base
-
查看event_base封裝的后端(當前系統中支持那些函數)
const char **event_get_supported_methods();
- 返回一個字符串數組中
const char * event_base_get_method(const struct event_base *base);
- 返回當前使用的IO轉接
-
event_base和fork
- 子進程創建成功后,父進程可以繼續使用event_base
- 子進程中需要繼續使用event_base需要重新進行初始化
int event_reinit(struct event_base * base)
事件 - event
- 創建新事件
#define EV_TIMEOUT 0x01 // 廢棄
#define EV_READ 0x02
#define EV_WRITE 0x04
#define EV_SIGNAL 0x08
#define EV_PERSIST 0x10 // 持續觸發
#define EV_ET 0x20 // 邊沿模式
typedef void(*event_callback_fn)(evutil_sockt_t,short,void *);
struct event *event_new(
struct event_base *base,
evutil_socket_t fd, // 文件描述符-int
shord what,
event_callback_fn cb, // 事件處理動作
void *arg
);
-
釋放事件
void event_free(struct event *event);
-
設置未決事件(有資格但是沒有被處理的事件)
- 構造事件之后,在將其添加到 event_base 之前實際上是不能對其做任何操作的。使用event_add()將事件添加到event_base, 非未決事件 -> 未決事件.
- 函數
int event_add( struct event *ev, const struct timeval *tv );
- tv:
- NULL: 事件被觸發, 對應的回調被調用
- tv = {0, 100}, 如果設置的時間,
- 在改時間段內檢測的事件沒被觸發, 時間到達之后, 回調函數還是會被調用
- 函數調用成功返回0, 失敗返回-1
-
設置非未決(還沒有資格被處理的事件)
int event_del(struct event *ev);
- 對已經初始化的事件調用 event_del()將使其成為非未決和非激活的。如果事件不是未決的或者激活的,調用將沒有效果。成功時函數返回 0,失敗時返回-1。
事件循環
-
開始循環
- 一旦有了一個已經注冊了某些事件的 event_base, 就需要讓 libevent 等待事件並且通知事件的發生。
#define EVLOOP_ONCE 0x01 事件只會被觸發一次 事件沒有被觸發, 阻塞等 #define EVLOOP_NONBLOCK 0x02 非阻塞 等方式去做事件檢測 不關心事件是否被觸發了 #define EVLOOP_NO_EXIT_ON_EMPTY 0x04 沒有事件的時候, 也不退出輪詢檢測
- int event_base_loop(struct event_base *base, int flags);
- 正常退出返回0, 失敗返回-1
event_base_dispatch(struct event_base* base)
- 等同於沒有設置標志的 event_base_loop()
- 將一直運行,直到沒有已經注冊的事件了,或者調用 了event_base_loopbreak()或者 event_base_loopexit()為止。
-
停止循環
- 返回值:成功0,失敗-1
struct timeval{ long tv_sec; long tv_usec; };
- 如果 event_base 當前正在執行激活事件的回調 ,它將在執行完當前正在處理的事件后立即退出
int event_base_loopexit( struct event_base *base, const struct timeval *tv );
- 讓event_base 立即退出循環
int event_base_loopbreak(struct event_base *base);