Libevent2.1和两个重要结构体
老接口 新接口
event.h: event2/event.h, event2/buffer.h event2/bufferevent.h event2/ tag.h
evdns.h: event2/dns*.h
evhttp.h: event2/http*.h
evrpc.h: event2/rpc*.h
evutil.h: event2/util*.h
在阅读Libevent源码时,会经常看到backend这个单词。其直译是“后端”。实际上其指的是Libevent内部使用的多路IO复用函数,多路IO复用函数就是select、poll、epoll这类函数
event结构体
struct event {
struct event_callback ev_evcallback; //回调函数
//1.最小堆管理定时器时间
union {
TAILQ_ENTRY(event) ev_next_with_common_timeout;
int min_heap_idx;
} ev_timeout_pos;
evutil_socket_t ev_fd; //IO事件:绑定的文件描述符;Signal事件:绑定的信号
//2.事件相关
short ev_events; //事件类型:I/O、信号、定时器事件
short ev_res; //当前激活事件的类型。调用回调函数时,传递给回调函数,保存回调函数的返回值
//3.Reactor管理者
struct event_base *ev_base; //event所属的Reactor
//4.io/signal事件链表
union {
/* used for io events */
struct {
LIST_ENTRY (event) ev_io_next;
struct timeval ev_timeout;
} ev_io;
/* used by signal events */
struct {
LIST_ENTRY (event) ev_signal_next;
short ev_ncalls;
/* Allows deletes in callback */
short *ev_pncalls;
} ev_signal;
} ev_;
struct timeval ev_timeout; //定时事件的超时值
};
从这个结构体看出来,包括3个方面的东西:
- 1.定时器相关
- 2.事件
- 3.Reactor管理者
- 4.事件链表
功能涵盖:
- 1.定时器事件
- 2.IO事件
- 3.信号事件
技巧
使用 union 來把IO、定時器、信号 三者合为一个结构体来管理,方便维护,并且是节省了内存的管理。这种做法在很多场景使用了,比如在内存池中,在内存池的各个槽的节点中包括了指向下个槽的地址,但是为了节省槽的结构体大小,会把next指针和节点数据用union封装起来,达到缩小结构体大小的目的。
ev_events的类型
- #define EV_TIMEOUT 0x01 //超时事件
- #define EV_READ 0x02 //读事件
- #define EV_WRITE 0x04 //写事件
- #define EV_SIGNAL 0x08 //信号事件
- #define EV_PERSIST 0x10 //永久事件
- #define EV_ET 0x20 //边缘触发事件
- #define EV_FINALIZE 0x40 //结束事件
- #define EV_CLOSED 0x80 //关闭事件
event_base结构体
struct event_base {
const struct eventop *evsel; //底层具体I/O demultiplex操作函数集
void *evbase; //底层base指针
struct event_changelist changelist; //改变事件的链表
const struct eventop *evsigsel; //底层base使用的消息回调指针
struct evsig_info sig; //信号句柄号
//对事件的一些统计
int virtual_event_count;
int virtual_event_count_max;
int event_count;
int event_count_max;
int event_count_active;
int event_count_active_max;
int event_gotterm;
int event_break;
int event_continue;
int event_running_priority;
int running_loop;
int n_deferreds_queued;
//激活事件队列
struct evcallback_list *activequeues;
int nactivequeues; //激活事件队列的长度
//事件回调函数。注册是延迟注册,系统在合适时间绑定
struct evcallback_list active_later_queue;
//定时器超时事件相关
struct common_timeout_list **common_timeout_queues;
int n_common_timeouts;
int n_common_timeouts_allocated;
//io、信号、定时信号的底层存放数据结构
struct event_io_map io; //io存放是map结构,查找快
struct event_signal_map sigmap; //map结构
struct min_heap timeheap; //最小堆
struct timeval tv_cache;
struct evutil_monotonic_timer monotonic_timer;
struct timeval tv_clock_diff;
time_t last_updated_clock_diff;
//涉及多线程的锁,条件变量,等待者等
#ifndef EVENT__DISABLE_THREAD_SUPPORT
unsigned long th_owner_id;
void *th_base_lock;
void *current_event_cond;
int current_event_waiters;
#endif
struct event_callback *current_event;
#ifdef _WIN32
struct event_iocp_port *iocp;
#endif
enum event_base_config_flag flags;
//Reactor调度相关
struct timeval max_dispatch_time;
int max_dispatch_callbacks;
int limit_callbacks_after_prio;
int is_notify_pending;
evutil_socket_t th_notify_fd[2];
struct event th_notify;
int (*th_notify_fn)(struct event_base *base);
struct evutil_weakrand_state weakrand_seed;
LIST_HEAD(once_event_list, event_once) once_events;
};