队列链表结构
队列双向循环链表实现文件:文件:src/core/ngx_queue.h/.c。在 Nginx 的队列实现中,实质就是具有头节点的双向循环链表,这里的双向链表中的节点是没有数据区的,只有两个指向节点的指针。需注意的是队列链表的内存分配不是直接从内存池分配的,即没有进行内存池管理,而是需要我们自己管理内存,所有我们可以指定它在内存池管理或者直接在堆里面进行管理,最好使用内存池进行管理。节点结构定义如下:
/* 队列结构,其实质是具有有头节点的双向循环链表 */
typedef struct ngx_queue_s ngx_queue_t;
/* 队列中每个节点结构,只有两个指针,并没有数据区 */
struct ngx_queue_s {
ngx_queue_t *prev;
ngx_queue_t *next;
};
队列链表操作
其基本操作如下:
/* h 为链表结构体 ngx_queue_t 的指针;初始化双链表 */
ngx_queue_int(h)
/* h 为链表容器结构体 ngx_queue_t 的指针; 判断链表是否为空 */
ngx_queue_empty(h)
/* h 为链表容器结构体 ngx_queue_t 的指针,x 为插入元素结构体中 ngx_queue_t 成员的指针;将 x 插入到链表头部 */
ngx_queue_insert_head(h, x)
/* h 为链表容器结构体 ngx_queue_t 的指针,x 为插入元素结构体中 ngx_queue_t 成员的指针。将 x 插入到链表尾部 */
ngx_queue_insert_tail(h, x)
/* h 为链表容器结构体 ngx_queue_t 的指针。返回链表容器 h 中的第一个元素的 ngx_queue_t 结构体指针 */
ngx_queue_head(h)
/* h 为链表容器结构体 ngx_queue_t 的指针。返回链表容器 h 中的最后一个元素的 ngx_queue_t 结构体指针 */
ngx_queue_last(h)
/* h 为链表容器结构体 ngx_queue_t 的指针。返回链表结构体的指针 */
ngx_queue_sentinel(h)
/* x 为链表容器结构体 ngx_queue_t 的指针。从容器中移除 x 元素 */
ngx_queue_remove(x)
/* h 为链表容器结构体 ngx_queue_t 的指针。该函数用于拆分链表,
* h 是链表容器,而 q 是链表 h 中的一个元素。
* 将链表 h 以元素 q 为界拆分成两个链表 h 和 n
*/
ngx_queue_split(h, q, n)
/* h 为链表容器结构体 ngx_queue_t 的指针, n为另一个链表容器结构体 ngx_queue_t 的指针
* 合并链表,将 n 链表添加到 h 链表的末尾
*/
ngx_queue_add(h, n)
/* h 为链表容器结构体 ngx_queue_t 的指针。返回链表中心元素,即第 N/2 + 1 个 */
ngx_queue_middle(h)
/* h 为链表容器结构体 ngx_queue_t 的指针,cmpfunc 是比较回调函数。使用插入排序对链表进行排序 */
ngx_queue_sort(h, cmpfunc)
/* q 为链表中某一个元素结构体的 ngx_queue_t 成员的指针。返回 q 元素的下一个元素。*/
ngx_queue_next(q)
/* q 为链表中某一个元素结构体的 ngx_queue_t 成员的指针。返回 q 元素的上一个元素。*/
ngx_queue_prev(q)
/* q 为链表中某一个元素结构体的 ngx_queue_t 成员的指针,type 是链表元素的结构体类型名称,
* link 是上面这个结构体中 ngx_queue_t 类型的成员名字。返回 q 元素所属结构体的地址
*/
ngx_queue_data(q, type, link)
/* q 为链表中某一个元素结构体的 ngx_queue_t 成员的指针,x 为插入元素结构体中 ngx_queue_t 成员的指针 */
ngx_queue_insert_after(q, x)
下面是队列链表操作源码的实现:
初始化链表
/* 初始化队列,即节点指针都指向自己,表示为空队列 */
#define ngx_queue_init(q) \
(q)->prev = q; \
(q)->next = q
/* 判断队列是否为空 */
#define ngx_queue_empty(h) \
(h == (h)->prev)
获取指定的队列链表中的节点
/* 获取队列头节点 */
#define ngx_queue_head(h)