一、前言
在 libevent 源码中,包括 注册事件队列(eventqueue) 和 激活事件队列(activequeues) 在内的很多地方都用到了 尾队列 这种数据结构。而 尾队列 的实现有点复杂,因此写一篇博客分析一下~
二、相关结构体
2.1 Entry结构体
libevent 中尾队列的 Entry(即尾队列元素) 结构体定义如下:
#define TAILQ_ENTRY(type) /* 尾队列 Entry */ \
struct {
\
struct type *tqe_next; /* 后一个 entry 的地址 */ \
struct type **tqe_prev; /* 前一个 entry 的 tqe_next 的地址 */ \
}
如代码所示,Entry 结构体包含了两个成员:
- tqe_next: 指向后一个 Entry
- tqe_prev: 指向前一个 Entry 的 tqe_next 的地址,由于 tqe_next 是一级指针,因此 tqe_prev 是二级指针
2.2 队头结构体
libevent 中尾队列的队头结构体定义如下:
#define TAILQ_HEAD(name, type) /* 尾队列队头 */ \
struct name {
\
struct type *tqh_first; /* 第一个 entry 的地址 */ \
struct type **tqh_last; /* 最后一个 entry 的 tqe_next 的地址 */ \
}
如代码所示,队头结构体包含了两个成员:
- tqh_first: 指向队列第一个 Entry
- tqh_last: 指向队列最后一个 Entry 的 tqe_next 成员的地址,由于 teq_next 是一级指针,因此 tqh_last 是二级指针
三、相关操作
3.1 定义尾队列
以 注册事件队列 为例,libevent 源码中定义尾队列的形式如下:
struct event_list;
TAILQ_HEAD (event_list, event);