Nginx模块开发—队列模型
来源:互联网 发布:让子弹飞 结局 知乎 编辑:程序博客网 时间:2024/06/06 06:55
1、数据结构
struct ngx_queue_s{ ngx_queue_t *prev; ngx_queue_t *next;};
备注:nginx的队列是由具有头节点的双向循环列表实现的,每个节点结构为ngx_queue_t,sizeof(ngx_queue_t)=8,nginx的队列结构里并没有其节点的数据内容。
2、队列操作
ngx_queue_init(q)
函数功能:初始化队列。#define ngx_queue_init(q) (q)->prev = q; (q)->next = q
ngx_queue_empty(h)
函数功能:判断队列是否为空。#define ngx_queue_empty(h) (h == (h)->prev)
ngx_queue_insert_head(h, x)
函数功能:在头节点之后插入新节点。#define ngx_queue_insert_head(h, x) (x)->next = (h)->next; (x)->next->prev = x; (x)->prev = h; (h)->next = x
ngx_queue_insert_after
函数功能:在头节点之后插入新节点。#define ngx_queue_insert_after ngx_queue_insert_head
ngx_queue_insert_tail(h, x)
函数功能:在尾节点之后插入新节点。#define ngx_queue_insert_tail(h, x) (x)->prev = (h)->prev; (x)->prev->next = x; (x)->next = h; (h)->prev = x
ngx_queue_head
函数功能:取出第一个节点。#define ngx_queue_head(h) (h)->next
ngx_queue_last
函数功能:取出最后一个节点。#define ngx_queue_last(h) (h)->prev
ngx_queue_next
函数功能:取出节点的后一个节点。#define ngx_queue_next(q) (q)->next
ngx_queue_prev
函数功能:取出节点的前一个节点。#define ngx_queue_prev(q) (q)->prev
ngx_queue_remove(x)
函数功能:删除节点。#define ngx_queue_remove(x) (x)->next->prev = (x)->prev; (x)->prev->next = (x)->next; (x)->prev = NULL; (x)->next = NULL
ngx_queue_split(h, q, n)
函数功能:分割队列。#define ngx_queue_split(h, q, n) (n)->prev = (h)->prev; (n)->prev->next = n; (n)->next = q; (h)->prev = (q)->prev; (h)->prev->next = h; (q)->prev = n;
函数解析:该宏有3个参数,h为队列头(即链表头指针),将该队列从q节点将队列分割为两个队列,q之后的节点组成的新队列的头节点为n,图形演示如下。
分割前:
分割后:
ngx_queue_add(h, n)
函数功能:链接队列。#define ngx_queue_add(h, n) (h)->prev->next = (n)->next; (n)->next->prev = (h)->prev; (h)->prev = (n)->prev; (h)->prev->next = h;
ngx_queue_data
#define ngx_queue_data(q, type, link) (type *) ((u_char *) q - offsetof(type, link))备注:offsetof主要用于求结构体中一个成员在该结构体中的偏移量,第一个参数是结构体的名字,第二个参数是结构体成员的名字。
ngx_queue_t *ngx_queue_middle(ngx_queue_t *queue)
函数功能:获取队列的中间节点,若队列有奇数个节点(除头节点外),则返回中间的节点,若队列有偶数个节点,则返回后半个队列的第一个节点。
算法思想:middle指针每次后移一个节点,而next指针每次后移两个节点。ngx_queue_t * ngx_queue_middle(ngx_queue_t *queue){ ngx_queue_t *middle, *next; middle = ngx_queue_head(queue); if (middle == ngx_queue_last(queue)) { return middle; } next = ngx_queue_head(queue); for ( ;; ) { middle = ngx_queue_next(middle); next = ngx_queue_next(next); if (next == ngx_queue_last(queue)) { //奇数个节点 return middle; } next = ngx_queue_next(next); if (next == ngx_queue_last(queue)) { //偶数个节点 return middle; }}}
void ngx_queue_sort(ngx_queue_t *queue,ngx_int_t (*cmp)(const ngx_queue_t*, const ngx_queue_t*))
函数功能:排序队列,使用的是稳定的插入排序。
算法思想:从第一个节点开始遍历,依次将当前节点q插入到前面已经排好序的队列链表中。Void ngx_queue_sort(ngx_queue_t *queue, ngx_int_t (*cmp)(const ngx_queue_t *, const ngx_queue_t *)){ ngx_queue_t *q, *prev, *next; q = ngx_queue_head(queue); if (q == ngx_queue_last(queue)) { return; } for (q = ngx_queue_next(q); q != ngx_queue_sentinel(queue); q = next) { prev = ngx_queue_prev(q); next = ngx_queue_next(q); ngx_queue_remove(q); do { if (cmp(prev, q) <= 0) { //比较节点 break; } prev = ngx_queue_prev(prev); } while (prev != ngx_queue_sentinel(queue)); ngx_queue_insert_after(prev, q); //依次将节点插入到已经排好序的队列链表中 }}
- Nginx模块开发—队列模型
- Nginx模块开发—数组模型
- Nginx模块开发 —进程模型
- nginx模块开发-定时器模型
- Nginx模块开发-日志模型
- Nginx模块开发(15)—日志模型
- Nginx基础知识. Nginx模块开发
- nginx开发学习——过滤模块
- Nginx模块开发入门
- Nginx模块开发入门
- nginx模块开发
- nginx模块开发说明
- Nginx模块开发
- NGINX模块开发
- Nginx Http模块开发
- Nginx 模块开发
- Nginx模块开发入门
- Nginx模块开发入门
- 常用浏览器内核及调试工具
- 使用Visual C++开发SOAP客户端应用
- C# 使用progressbar演示后台进程当前状态
- Linux系统建立Nor Flash分区
- mysql 命令行创建数据库操作个人学习
- Nginx模块开发—队列模型
- C#简单整理
- 使用数组实现大整数加法
- POJ 3304 Segments
- SecureCRT rz 工具上传某些格式的文件出错的解决办法
- android拦截短信
- linux下C函数调用机制(X86平台)
- Java编程思想阅读笔记
- Oracle CBO RBO