Libevent源码分析——队列

本文详细分析了Libevent中队列的数据结构,包括TAILQ_ENTRY的使用,以及一级指针tqh_first和二级指针tqh_last如何指示队列。队列操作宏如TAILQ_LAST和TAILQ_PREV等被讨论,特别强调了内存布局和指针之间的关系,解释了如何通过指针获取队列元素的值。
摘要由CSDN通过智能技术生成
在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((
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值