libevent数据结构尾队列
1.概述
最近找来libevent的源码学习了一下,看到用宏实现的数据结构甚是惊讶,把其中尾队列的代码copy出来test了一下.个人感觉用宏实现该队列的思想是C++的模板的思想.我自己实现一个队列的思路肯定是写一个队列 中节点的结构体然后针对该结构体实现队列的基本操作.这样的队列只能使用于写好的节点….而libevent实现的版本是不依赖于实际的节点的.换句话说,我们有两个类,一个student,一个teacher,该队列既可以把student 作为队列连接起来,也可以将teacher连接起来.相当于 TAIQ ,TAIQ. 而且针对同一个结构体(类) 可以实现多个队列,比如说所有学生连接成一个队列,再把其中的男学生连接为一个队列.
2实现
#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 */ \
}/** tail queue access methods*/
#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((var) = TAILQ_LAST(head, headname); \(var) != TAILQ_END(head); \(var) = TAILQ_PREV(var, headname, field))/** Tail queue functions.*/
#define TAILQ_INIT(head) do { \(head)->tqh_first = NULL; \(head)->tqh_last = &(head)->tqh_first; \
} while (0)#define TAILQ_INSERT_HEAD(head, elm, field) do { \if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \(head)->tqh_first->field.tqe_prev = \&(elm)->field.tqe_next; \else \(head)->tqh_last = &(elm)->field.tqe_next; \(head)->tqh_first = (elm); \(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (0)#define TAILQ_INSERT_TAIL(head, elm, field) do { \(elm)->field.tqe_next = NULL; \(elm)->field.tqe_prev = (head)->tqh_last; \*(head)->tqh_last = (elm); \(head)->tqh_last = &(elm)->field.tqe_next; \
} while (0)#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\(elm)->field.tqe_next->field.tqe_prev = \&(elm)->field.tqe_next; \else \(head)->tqh_last = &(elm)->field.tqe_next; \(listelm)->field.tqe_next = (elm); \(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (0)#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \(elm)->field.tqe_next = (listelm); \*(listelm)->field.tqe_prev = (elm); \(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)#define TAILQ_REMOVE(head, elm, field) do { \if (((elm)->field.tqe_next) != NULL) \(elm)->field.tqe_next->field.tqe_prev = \(elm)->field.tqe_prev; \else \(head)->tqh_last = (elm)->field.tqe_prev; \*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
} while (0)#define TAILQ_REPLACE(head, elm, elm2, field) do { \if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \(elm2)->field.tqe_next->field.tqe_prev = \&(elm2)->field.tqe_next; \else \(head)->tqh_last = &(elm2)->field.tqe_next; \(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \*(elm2)->field.tqe_prev = (elm2); \
} while (0)
3测试
针对最后一个功能点进行了简单的测试,以加深记忆和理解
#include "queue.h"
#include <stdio.h>
#include <stdlib.h>
#define NQUEUE 5
struct event{TAILQ_ENTRY(event) queue_field;TAILQ_ENTRY(event) active_queue_field;int start;
};
TAILQ_HEAD(eventqueue,event);
TAILQ_HEAD(activequeue,event);struct eventqueue event_queue_head;
struct activequeue active_queue_head;
void init(){TAILQ_INIT(&event_queue_head);TAILQ_INIT(&active_queue_head);
}
int main(){init();int i;struct event *e = NULL;for(i = 0; i < NQUEUE; i++){e =(struct event*)malloc(sizeof(struct event));e->start = i;TAILQ_INSERT_TAIL(&event_queue_head,e,queue_field);if(i %2 == 0)TAILQ_INSERT_TAIL(&active_queue_head,e,active_queue_field);}struct event* var = NULL;TAILQ_FOREACH(var,&event_queue_head,queue_field){printf("the value is %d\n",var->start);}printf("\n");TAILQ_FOREACH(var,&active_queue_head,active_queue_field){printf("the value is %d\n",var->start);}return 0;}
实现了一个结构体 event , 申请了5个event 并把它们连接成两个队列.一个队列中包含了所有的event,一个队列中包含了值为偶数的event.
打印结果:
~/xxxx ᐅ ./a.out
the value is 0
the value is 1
the value is 2
the value is 3
the value is 4the value is 0
the value is 2
the value is 4
libevent数据结构尾队列相关推荐
- libevent(二)尾队列 最小堆
本文主要研究libevent中用来存储事件的两个结构体. 尾队列 具体定义位于queue.h中. #define TAILQ_HEAD(name, type) \ struct name { \str ...
- c++ 优先队列_C/C++数据结构:队列结构最全解析!带你零基础入门队列结构
前言 上一章节针对于C语言栈结构做了解析,不清楚的可以回顾一下. 本章节主要针对于C语言的基础数据结构队列做以解析. 数据结构之队列 队列是一种特殊的 线性表 ,特殊之处在于它只允许在表的前端(fro ...
- java 头尾 队列_Java数据结构之队列(动力节点Java学院整理)
队列的定义: 队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表. (1)允许删除的一端称为队头(Front). (2)允许插入的一端称为队尾(Rear). (3)当队列中 ...
- python环形队列_Python 实现数据结构-循环队列的操作方法
今天我们来到了循环队列这一节,之前的文章中,我介绍过了用python自带的列表来实现队列,这是最简单的实现方法. 但是,我们都知道,在列表中删除第一个元素和删除最后一个元素花费的时间代价是不一样的,删 ...
- 数据结构——环形队列的原理(模拟环形队列)
数据结构--环形队列的原理(模拟环形队列) 知识点简要介绍: 队列:一种特殊的线性表,包含队列头.队列尾,只允许在队列头进行删除操作,在队列为进行删除操作 分类: 顺序队列.循环队列(环形队列 ...
- c语言数据结构之队列
前言 不同于栈,队列是一个先进先出的数据结构,规定数据节点从队列尾插入,从队列头取出,禁止对头尾两端以外的数据进行操作.队列可以分为顺序队列和循环队列. C语言数据结构之单链表 C语言数据结构之双向链 ...
- C语言之尾队列tailq
from http://blog.csdn.net/xiaojun111111/article/details/51752471 queue和list的结构定义和操作都在'sys/queue.h'中 ...
- 【数据结构】 队列的简单理解和基本操作
前言:本章介绍的主要内容是数据结构中队列的概念,并通过代码实现链式结构的队列. 文章目录 1.队列的基本概念 1.1 队列的定义 1.2 队列的特点 2.队列的代码实现 2.1 队列存储的说明 2.2 ...
- 数据结构--环形队列的介绍与实现
数据结构--环形队列实现 一.环形队列实现原理 环形队列的几个判断条件 二.代码实现 1.环形队列类(CircleQueue) 2.环形队列类测试类 3.程序运行结果 4.完整代码 环形队列可以用数组 ...
最新文章
- 在64-bit机器上运行32-big的应用程序,需要安装ia32-libs库
- windows下安装whl文件
- 【Linux 内核】CFS 调度器 ① ( CFS 完全公平调度器概念 | CFS 调度器虚拟时钟 Virtual Runtime 概念 | 四种进程优先级 | 五种调度类 )
- 机器人锤石下路组合_下周二,极智嘉研发总监讲解物流机器人视觉感知与定位关键技术...
- linux 低功耗运行,关于Linux的快速启动(fastboot)和低功耗(low power)的学习记录...
- Spring开启@Async异步方法(javaconfig配置)
- 一群人围成一圈从123报数,如果报到3就退出该圈中,直到最后一个人留下来!...
- 计算机科学导论课后感悟,计算机科学导论课后总结_2
- raid0 raid1 raid5 raid10工作模式的工作原理及特点
- 美女DBA带你了解PostgreSQL用户及角色
- [走走看看]转载两篇文章:挂牌和追经
- CSDN 文章自动显示全文
- 58. web 攻击技术(2)
- c# 多线程单例模式_线程安全C#单例模式
- 走出校门,重新起航,从纯粹到再次纯粹
- 数据结构课程设计:17、售票处的服务系统(***)
- 谷歌浏览器Chrome被hao123劫持怎么解决?---- 被hao123、2345、360等主页劫持和捆绑的解决方法
- revit服务器维护,Revit server是什么?Revit Server 管理有问题,谁来解决、怎么解决?...
- Windows 7 x64 SP1 安装 Windows Edge 浏览器
- java 判断是不是图片_java判断是否是图片