Nginx源码阅读:ngx_list_t 链表

简介: Nginx源码阅读:ngx_list_t 链表

一、Nginx中链表(ngx_list_t)的结构图

ngx_list_t作为一个链表的结构体,里面是一些链表的信息,ngx_list_part_t是链表的节点。

ngx中的链表并不是将内存简单串起来,而是将内存组织成块(chunck,在ngx中叫part),然后将这些块通过链表串起来。

每个块划分为nalloc片区域,每片区域的大小为size,因此一个chunck的大小为n*nalloc

一个chunck中已分配的区域片数为nelts

二、源码阅读

1、ngx_list_part_s

//一个chunk块(part)
struct ngx_list_part_s {
    void             *elts;  //数据区域首地址的指针
    ngx_uint_t        nelts; //已分配的数据区域的个数
    ngx_list_part_t  *next;  //下一个chunck(part)
};

2、ngx_list_t

链表的结构体,包含一些链表的信息,用于将(chunck)part组织起来

//链表,用来组织chunk块
typedef struct {
    ngx_list_part_t  *last;     //最后一块chunck
    ngx_list_part_t   part;     //第一块chunck
    size_t            size;     //一个片的大小为size(一个chunck分为nalloc片,那么一个chunck大小为nalloc*size)
    ngx_uint_t        nalloc;   //一个chunck划分成nalloc片区域
    ngx_pool_t       *pool;     //所属的内存池
} ngx_list_t;

3、ngx_list_create

创建一个链表,首先要从内存池中分配一块数据给list结构体,然后再交给ngx_list_init去初始化具体信息,和分配数据区域空间。

ngx_list_t *
ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
    ngx_list_t  *list;
    list = ngx_palloc(pool, sizeof(ngx_list_t));//从内存池分配一块数据,用于存储list结构体
    if (list == NULL) {
        return NULL;
    }
    if (ngx_list_init(list, pool, n, size) != NGX_OK) {//初始化
        return NULL;
    }
    return list;
}

4、ngx_list_init

初始化list结构体的信息,并分配一块chunck

static ngx_inline ngx_int_t
ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
    list->part.elts = ngx_palloc(pool, n * size);//创建一块chunck的数据区域,大小为 片数量*每个片的空间大小
    if (list->part.elts == NULL) {
        return NGX_ERROR;
    }
    list->part.nelts = 0;//初始化的时候,还没将空间使用,因此是0
    list->part.next = NULL;
    list->last = &list->part;//初始化的时候最后一块chunck就是第一块
    list->size = size;//初始化的数据大小
    list->nalloc = n;
    list->pool = pool;//所属的内存池
    return NGX_OK;
}

5、ngx_list_push

通过list来获取一块空间的首地址。

取一块数据为什么叫push呢?因为数据是通过list组织起来的,分配的空间通过list来组织,也就是要push到list中的。

void *
ngx_list_push(ngx_list_t *l)
{
    void             *elt;
    ngx_list_part_t  *last;
    last = l->last;//list中最后一个chunck
    if (last->nelts == l->nalloc) {//如果最后一块chunck中的片已经全部使用完了,那么就要新创建一个chunck,以及空间大小
        /* the last part is full, allocate a new list part */
        last = ngx_palloc(l->pool, sizeof(ngx_list_part_t));//创建chunck头的空间
        if (last == NULL) {
            return NULL;
        }
        last->elts = ngx_palloc(l->pool, l->nalloc * l->size);//创建chunck数据空间
        if (last->elts == NULL) {
            return NULL;
        }
        last->nelts = 0;//已使用的片的数量为0
        last->next = NULL;
        l->last->next = last;//新创建的chunck为最后一个chunk
        l->last = last;
    }
    elt = (char *) last->elts + l->size * last->nelts;//返回可以使用的内存空间地址(根据当前chunck中已经使用的片数量)
    last->nelts++;//当前chunck中使用的片数量+1
    return elt;
}
相关文章
|
应用服务中间件 Linux 网络安全
CentOS 7.4源码编译nginx1.12 并且隐藏nginx的版本
CentOS 7.4源码编译nginx1.12 并且隐藏nginx的版本
197 0
|
10月前
|
编译器 C语言 C++
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
206 1
|
11月前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
859 4
|
12月前
|
存储 Java
HashMap之链表转红黑树(树化 )-treefyBin方法源码解读(所有涉及到的方法均有详细解读,欢迎指正)
本文详细解析了Java HashMap中链表转红黑树的机制,包括树化条件(链表长度达8且数组长度≥64)及转换流程,确保高效处理大量数据。
502 1
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
193 2
|
11月前
|
C语言
【数据结构】双向带头循环链表(c语言)(附源码)
本文介绍了双向带头循环链表的概念和实现。双向带头循环链表具有三个关键点:双向、带头和循环。与单链表相比,它的头插、尾插、头删、尾删等操作的时间复杂度均为O(1),提高了运行效率。文章详细讲解了链表的结构定义、方法声明和实现,包括创建新节点、初始化、打印、判断是否为空、插入和删除节点等操作。最后提供了完整的代码示例。
327 0
|
负载均衡 网络协议 应用服务中间件
web群集--rocky9.2源码部署nginx1.24的详细过程
Nginx 是一款由 Igor Sysoev 开发的开源高性能 HTTP 服务器和反向代理服务器,自 2004 年发布以来,以其高效、稳定和灵活的特点迅速成为许多网站和应用的首选。本文详细介绍了 Nginx 的核心概念、工作原理及常见使用场景,涵盖高并发处理、反向代理、负载均衡、低内存占用等特点,并提供了安装配置教程,适合开发者参考学习。
230 1
|
12月前
|
存储 缓存 应用服务中间件
Nginx入门 -- 基本数据结构中之ngx_list_t,ngx_queue_t
Nginx入门 -- 基本数据结构中之ngx_list_t,ngx_queue_t
217 0
【数据结构】双向带头(哨兵位)循环链表 —详细讲解(赋源码)
【数据结构】双向带头(哨兵位)循环链表 —详细讲解(赋源码)
183 4
|
应用服务中间件 Linux nginx
在CentOS上使用源码包安装Nginx、以及手动启动Nginx的步骤过程
这篇文章介绍了在CentOS系统上使用Nginx源码包进行安装和配置的详细步骤,包括源码包的获取、解压、配置、编译、安装、启动验证以及注意事项。
837 0
在CentOS上使用源码包安装Nginx、以及手动启动Nginx的步骤过程