libevent 使用流程


libevent 使用流程

使用流程

  1. 創建一個事件處理框架
  2. 創建一個事件
  3. 事件添加到處理框架
  4. 開始事件循環
  5. 釋放資源

事件處理框架 - event_base

  1. 使用libevent函數之前需要分配一個或者多個event_base結構體. 每個event_base結構體有一個事件集合,可以檢測以確定哪個事件是激活的.

    • 相當於epoll紅黑樹的樹根
    • 底座
    • 抽象層,完成對event_base的封裝
    • 每個event_base都有一種用於檢測那種事件已經就緒的"方法",或者說后端
  2. 具體操作

    • 創建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);
  3. 查看event_base封裝的后端(當前系統中支持那些函數)

    • const char **event_get_supported_methods();
    • 返回一個字符串數組中
    • const char * event_base_get_method(const struct event_base *base);
    • 返回當前使用的IO轉接
  4. event_base和fork

    • 子進程創建成功后,父進程可以繼續使用event_base
    • 子進程中需要繼續使用event_base需要重新進行初始化
      • int event_reinit(struct event_base * base)

事件 - event

  1. 創建新事件

#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
);
  1. 釋放事件

    • void event_free(struct event *event);
  2. 設置未決事件(有資格但是沒有被處理的事件)

    • 構造事件之后,在將其添加到 event_base 之前實際上是不能對其做任何操作的。使用event_add()將事件添加到event_base, 非未決事件 -> 未決事件.
    • 函數
      int event_add(
          struct event *ev, 
          const struct timeval *tv
      ); 
      
    • tv:
      • NULL: 事件被觸發, 對應的回調被調用
      • tv = {0, 100}, 如果設置的時間,
        • 在改時間段內檢測的事件沒被觸發, 時間到達之后, 回調函數還是會被調用
    • 函數調用成功返回0, 失敗返回-1
  3. 設置非未決(還沒有資格被處理的事件)

    • int event_del(struct event *ev);
    • 對已經初始化的事件調用 event_del()將使其成為非未決和非激活的。如果事件不是未決的或者激活的,調用將沒有效果。成功時函數返回 0,失敗時返回-1。

事件循環

  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()為止。
  2. 停止循環

    • 返回值:成功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);
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM