1. 程式人生 > >libevent(三)event_base

libevent(三)event_base

16px pat alloc mage signal .com events vba alt

libevent能夠處理三種事件: I/O、信號、定時器。

涉及兩個數據結構:

  event,表示一個事件

  event_base,管理所有事件

本文主要介紹event_base,結構如下:

struct event_base {
    const struct eventop *evsel;        // backend
    void *evbase;
    
    const struct eventop *evsigsel;
    struct evsig_info sig;
    
    int event_count;                    // 事件總數
int event_count_active; // 活躍事件總數 struct event_list eventqueue; // 存儲所有事件 struct event_io_map io; // 存儲I/O事件 struct event_signal_map sigmap; // 存儲信號事件 struct min_heap timeheap; // 存儲定時器事件 struct event_list *activequeues; // 存儲激活事件 int
nactivequeues; // 激活隊列個數 struct timeval event_tv; struct timeval tv_cache; void *th_base_lock; int is_notify_pending; evutil_socket_t th_notify_fd[2]; struct event th_notify; int (*th_notify_fn)(struct event_base *base); ... };

evsel主要描述libevent的底層實現機制,linux系統對應epoll。

/** Structure to define the backend of a given event_base. */
struct eventop {
    const char *name;
    void *(*init)(struct event_base *);
    int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
    int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
    int (*dispatch)(struct event_base *, struct timeval *);
    void (*dealloc)(struct event_base *);
    int need_reinit;
    enum event_method_feature features;
    size_t fdinfo_len;
};

const struct eventop epollops = {
    "epoll",
    epoll_init,
    epoll_nochangelist_add,
    epoll_nochangelist_del,
    epoll_dispatch,
    epoll_dealloc,
    1, /* need reinit */
    EV_FEATURE_ET|EV_FEATURE_O1,
    0
};

event_list是一個雙向鏈表,min_heap是一個小根堆,而event_io_map結構有點復雜。

在linux系統,event_io_map就是event_signal_map,結構如下:

struct event_signal_map {
    void **entries; /* An array of evmap_io * or of evmap_signal */
    int nentries;
};

struct evmap_io {
    struct event_list events;
    ev_uint16_t nread;
    ev_uint16_t nwrite;
};

struct evmap_signal {
    struct event_list events;
};

一圖勝千言:

技術分享

可以看出,一個event_signal_map對應多個雙向鏈表。同一個fd或signal的事件位於同一個鏈表中。

libevent(三)event_base