Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

Nginx提供了轻量级的双向链表,仅有指针域,而无数据域.用户在使用的时候需要自定义一个包含了这个指针域的结构体,其指针域定义如下:

typedef struct ngx_queue_s  ngx_queue_t;struct ngx_queue_s {ngx_queue_t  *prev; // 前置指针域ngx_queue_t  *next; // 后置指针域
};


用户使用的图示:

大概扫了一眼实现的源码,看了下风格,我模仿它写了一个双向循环链表.

初始化

提示:
方法名: ngx_queue_init(h)

参数含义: h为链表容器结构体ngx_queue_t的指针

执行意义: 将链表容器初始化,这时会自动置为空链表

#define ngx_queue_init(q)    \(q) -> prev = q;           \(q) -> next = q;

判空

提示:
方法名: ngx_queue_empty(h)

参数含义: h为链表容器结构体ngx_queue_t的指针

执行意义: 检测链表容器中是否为空,即是否没有一个元素存在.如果返回非0,表示链表h是的.

#define ngx_queue_empty(q)   \(q == (q) -> prev)

插入元素

此处使用的思想正如我在之前的《单链表》一文中写的链表插入的思想,归纳为八个字:先斩后奏,先左后右.传送链接:单链表
提示:
方法名: ngx_queue_insert_head(h,x)

参数含义: h为链表容器结构体ngx_queue_t的指针,x为插入元素结构体中ngx_queue_t成员的指针

执行意义: 将元素x插入到链表容器h的头部

#define ngx_queue_insert_head(q,x)   \(x) -> prev = q;               \(x) -> next = (q) -> next;      \(q) -> next -> prev = x;        \(q) -> next = x;

提示:
方法名: ngx_queue_insert_tail(h,x)

参数含义: h为链表容器结构体ngx_queue_t的指针,x为插入元素结构体中ngx_queue_t成员的指针

执行意义: 将元素x插入到链表容器h的末尾

#define ngx_queue_insert_tail(q,x)   \(x) -> prev = (q) -> prev;      \(x) -> next = q;               \(q) -> prev -> next = x;        \(q) -> prev = x;

查找

提示:
方法名: ngx_queue_head(h)

参数含义: h为链表容器结构体ngx_queue_t的指针

执行意义: 返回链表容器h中的第一个元素的ngx_queue_t结构体指针

#define ngx_queue_head(q)    \(q) -> next

提示:
方法名: ngx_queue_last(h)

参数含义: h为链表容器结构体ngx_queue_t的指针

执行意义: 返回链表容器h中的最后一个元素的ngx_queue_t结构体指针

#define ngx_queue_last(q)    \(q) -> prev

提示:
方法名: ngx_queue_next(q)

参数含义: q为链表中某一个元素结构体的ngx_queue_t成员的指针

执行意义: 返回q元素的下一个元素

#define ngx_queue_next(q)    \(q) -> next

提示:
方法名: ngx_queue_prev(q)

参数含义: q为链表中某一个元素结构体的ngx_queue_t成员的指针

执行意义: 返回q元素的上一个元素

#define ngx_queue_prev(q)    \(q) -> prev

删除

提示:
方法名: ngx_queue_remove(x)

参数含义: x为插入元素结构体中ngx_queue_t成员的指针

执行意义: 由容器中移除x元素

#define ngx_queue_remove(x)  \(x) -> prev -> next = (x) -> next;       \(x) -> next -> prev = (x) -> prev;

寻址

提示:
方法名: ngx_queue_data(q, type, link)

参数含义: q为链表中某一个元素结构体中ngx_queue_t成员的指针,type为链表元素的结构体类型名称(该结构体中必须包含ngx_queue_t类型的成员),link是上面这个结构体重ngx_queue_t类型的成员名字

执行意义: 返回q元素(ngx_queue_t类型)所属结构体(任何struct类型,其中可在任意位置包含ngx_queue_t类型的成员)的地址

#define ngx_queue_data(q, type, link)    \(type *)((unsigned char *)q - offsetof(type, link))

这里用到了offsetof这个宏.

C 库宏 offsetof(type, member-designator) 会生成一个类型为 size_t 的整型常量,它是一个结构成员相对于结构开头的字节偏移量。成员是由 member-designator 给定的,结构的名称是在 type 中给定的。

全部代码及测试代码

这里只测试了部分宏函数.

#include <iostream>using namespace std;typedef struct ngx_queue_s  ngx_queue_t;struct ngx_queue_s {ngx_queue_t  *prev; // 前置指针域ngx_queue_t  *next; // 后置指针域
};#define ngx_queue_init(q) \(q) -> prev = q;           \(q) -> next = q;#define ngx_queue_empty(q) \(q == (q) -> prev)#define ngx_queue_insert_head(q,x)  \(x) -> prev = q;               \(x) -> next = (q) -> next;      \(q) -> next -> prev = x;        \(q) -> next = x;#define ngx_queue_insert_tail(q,x) \(x) -> prev = (q) -> prev;      \(x) -> next = q;               \(q) -> prev -> next = x;        \(q) -> prev = x;#define ngx_queue_head(q)  \(q) -> next#define ngx_queue_last(q)    \(q) -> prev#define ngx_queue_remove(x)  \(x) -> prev -> next = (x) -> next;       \(x) -> next -> prev = (x) -> prev;#define ngx_queue_next(q)  \(q) -> next#define ngx_queue_prev(q)    \(q) -> prev#define ngx_queue_data(q, type, link)    \(type *)((unsigned char *)q - offsetof(type, link))typedef struct {ngx_queue_t p;int data;
}User;//用户自定义结构体void printNginx(ngx_queue_t *node) {ngx_queue_t *e = ngx_queue_head(node);//第一个结点while (e != node) {User *node = ngx_queue_data(e, User, p);//寻址cout << node->data << "\t";e = ngx_queue_next(e);}cout << endl;
}int main(void) {User *user=new User;ngx_queue_t *head = &(user->p);//头结点ngx_queue_init(head);if (ngx_queue_empty(head)) {cout << "链表为空!" << endl;}int n;cout << "请输入插入元素的个数(正在使用头插法):";cin >> n;while (n--) {User *node=new User;ngx_queue_t *e = &(node->p);cout << "请输入元素的数据:";cin >> node->data;ngx_queue_insert_head(head, e);}printNginx(head);system("pause");return 0;
}


事实上,在写测试代码的时候相当困难,中间改写了很多次,其根本原因是不熟悉其体现的思想.不过好在多次思考,断点调试,揣摩代码,最终才有了这篇文章.

由Nginx源码写双向循环链表相关推荐

  1. Nginx源码分析-内存池

    本文转自淘宝平台http://www.tbdata.org/archives/1390,不是为了夺他人之美,只是觉得写得很好,怕淘宝万一删掉就找不到了,放在这里保存一下.大家可以直接链接过去,他们那个 ...

  2. 从Nginx源码谈大小写字符转化的最高效代码以及ASCII码表的科学

    说起大小写字母转换,大家很容易想起系统函数是不是,几乎所有的编程语言都提供了这种转换函数,但是你有没有想过这背后是怎么实现的? 让你写怎么实现? 我们都知道Nginx是目前用的最多的Http服务器,那 ...

  3. Nginx源码分析--数据对齐posix_memalign和memalign函数

    posix_memalign函数() /*  * 背景:  *      1)POSIX 1003.1d  *      2)POSIX 标明了通过malloc( ), calloc( ), 和 re ...

  4. Nginx源码分析:epoll事件处理模块概述

    nginx源码分析 nginx-1.11.1 参考书籍<深入理解nginx模块开发与架构解析> 事件处理模块概述 Nginx的高效请求的处理依赖于事件管理机制,本次默认的场景是Linux操 ...

  5. Nginx源码分析:核心数据结构ngx_cycle_t与内存池概述

    nginx源码分析 nginx-1.11.1 参考书籍<深入理解nginx模块开发与架构解析> 核心数据结构与内存池概述 在Nginx中的核心数据结构就是ngx_cycle_t结构,在初始 ...

  6. 设计模式在C语言中的应用--读nginx源码

    市面上的"设计模式"书籍文章,皆针对Java/C++/C#等面向对象语言,似乎离开了面向对象的种种特性,设计模式就无法实现,没有用武之地了. 是这样吗?设计模式的概念是从建筑领域引 ...

  7. nginx源码分析—内存池结构ngx_pool_t及内存管理

    本博客( http://blog.csdn.net/livelylittlefish)贴出作者(阿波)相关研究.学习内容所做的笔记,欢迎广大朋友指正! Content 0.序 1.内存池结构 1.1 ...

  8. Nginx 源码分析-- 模块module 解析执行 nginx.conf 配置文件流程分析 一

    搭建nginx服务器时,主要的配置文件 nginx.conf 是部署和维护服务器人员经常要使用到的文件, 里面进行了许多服务器参数的设置.那么nginx 以模块 module为骨架的设计下是如何运用模 ...

  9. nginx 源码调试

    nginx 源码调试 这段时间正在学习nginx源码,看到一贴子的提问 (帖子:http://www.oschina.net/question/2711991_2165566?p=1#AnchorAn ...

最新文章

  1. 广东电大计算机绘图试题,电大计算机绘图期末复习试题及答案参考小抄.doc
  2. Windows 7 RC Build 7100 使用报告
  3. Theme.NoTitleBar问题
  4. swiper 在turn.js不能滚动
  5. python截图识别文字_用百度ocr+微信截图实现文字识别
  6. Ribbon和Feign的对比-带简易例子
  7. SQL server 數據庫 從SQL2000搬移到SQL2016
  8. 微信语音红包小程序开发如何提高精准度 红包小程序语音识别精准度 微信小程序红包开发语音红包...
  9. 扩展欧几里得算法的讲解
  10. 计算机及数码产品营销课后题,职业教育课程改革创新系列教材:计算机及数码产品营销...
  11. 开启win10隐藏语音库
  12. 设置linux kernel 日志打印方法
  13. flutter floor数据库框架使用
  14. 2022软件测试自学路线分享,附完整资料,自学也能拿高薪哟
  15. 【论文导读】Causal Protein-Signaling Networks Derived from Multiparameter Single-Cell Data
  16. jni使用(四)-----IDEA中javah生成.h文件
  17. 【达摩院OpenVI】AIGC技术在图像超分上的创新应用
  18. Air724UG HCore-A724UG YunDTU固件
  19. [Paper Reading] Towards Conversational Recommendation over Multi-Type Dialogs
  20. Install xe-guest-utilities in PfSense 2.3

热门文章

  1. 手机如何实现边有线上网边充电?
  2. 真实评测:华为nova8和红米k30至尊版哪个好-参数区别对比
  3. 133、初沸点的概念
  4. mac 文件上传服务器
  5. 微信小程序聊天客服工具
  6. C语言刷题系列——5.使用函数判断完全平方数
  7. 网站是用什么来赚钱的?
  8. groovy快速上手第2篇:数据类型篇
  9. 《大明王朝》雪崩前,精英们的狂欢
  10. SSD算法理解(1)