在compat/sys/queue.h文件里定义了5种数据结构,分别是单链表、双链表、简单队列、尾队列、环形队列,其中
TAILQ_QUEUE尾队列是libevent里使用最多的,
libevent中用到的队列其实也是尾队列
,所以
这里只分析尾队列
TAILQ_QUEUE
,
其
他结构都大同小异,
TAILQ_QUEUE
队列的结构体如下:
/*
* Tail queue definitions.
*/
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}
TAILQ_ENTRY没有结构体名,所以它一般都是另外一个结构体的成员,tqe_next和tqh_frist是一级指向结构体地址,tqh_last和tqh_prev是二级指针,也就是指向指针的指针,所以指向队列的next指针,构造出来的队列一般如下图所示:
队列操作宏函数如下:
//队列中的第一个元素
#define TAILQ_FIRST(head) ((head)->tqh_first)
//队列结束
#define TAILQ_END(head) NULL
//队列中当前元素的下一个节点
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
//队列最后一个节点
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
/* XXX */
//队列前一个节点
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
//队列是否为空
#define TAILQ_EMPTY(head) \
(TAILQ_FIRST(head) == TAILQ_END(head))
//队列遍历
#define TAILQ_FOREACH(var, head, field) \
for((var) = TAILQ_FIRST(head); \
(var) != TAILQ_END(head); \
(var) = TAILQ_NEXT(var, field))
//队列从尾遍历
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for((