libevent中的尾队列tailq分析

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

libevent中的tailq本质上, 就是一个双向链表, 然后记录下了头指针和尾指针, 便于顺序遍历和逆序遍历.

由于C语言中没有模板, 为了适应不同的数据类型, tailq的操作, 都是使用的宏定义, 导致代码难以阅读.

为了方便分析, 本文对tailq相关的结构体进行了简化:

struct tailq{
    struct element*  first;
    struct element** last;
};
struct element{
    struct element*  next; //next必须放在第一个位置
    struct element** prev;
    int x;//这里表示结构体中的其它成员
};

读者可能有以下一些疑问:

1. last和prev为什么要使用指针地址, 直接用struct element*不是更简洁明了吗?

看下面这段代码:    

struct element** prev;
struct element* elem = malloc(sizeof(struct element));
prev = &elem->next;

根据C语言的规则

因为elem == &elem->next

所以: prev == elem

即:  next的值elem指针, prev的值也是elem的指针, 只不过形式上是struct element**, 使用时, 可以直接强转为struct elemnt*来操作

写了一个普通的双向链表, 与之对比, 得出的结论是, tailq使用指针地址方式, insert_tail的操作少了一条if语句判断, 效率上更优.

2. 数据存储的结构是怎样的, 根据代码表面上的意义, 可以画出这样一张图:

绿色表示整个element

蓝色表示字段

白色表示值

libevent中的尾队列tailq分析_第1张图片

由于&next的值, 等于element指针, 所以上图可以演变成

libevent中的尾队列tailq分析_第2张图片

这样, 就很清晰了, prev指向前一个元素, next指向后一个元素, first指向第一人元素, last指向最后一个元素

转载于:https://my.oschina.net/u/2343729/blog/795059

你可能感兴趣的:(libevent中的尾队列tailq分析)