Nginx单向链表 ngx_list_t

目录

基本概述

数据结构

接口描述

具体实现

ngx_list_create

ngx_list_init

ngx_list_push

使用案例


整理自 nginx 1.9.2 源码 和 《深入理解 Nginx:模块开发与架构解析》

基本概述

        Nginx 中的 ngx_list_t 是一个单向链表容器,链表中的每一个节点同时又是数据数组。ngx_list_t 作为链表容器,确定了 ngx_list_part_s 节点的存储空间容量、内存管理入口(内存池)和数据访问入口(链表+数组)。

        ngx_list_t  链表具体结构如下图所示。可灵活定义 ngx_list_part_s 中数据结构,同时因为其内部存储地址连续,可通过数组偏移进行快速访问。

数据结构

typedef struct ngx_list_part_s  ngx_list_part_t; /*链表中的一个节点,该节点中的 elts 记录一个数组的数据,数组类型可以自定义 ;节点使用的数组,容量(成员个数)已经固定(由 ngx_list_t 中的 nalloc 确定),使用 nelts 记录该数组已使用容量,所以 nelts 肯定小于 nalloc
*/
struct ngx_list_part_s { void             *elts;   // 指向数组的起始地址。ngx_uint_t        nelts;  // 数组已使用了多少个元素ngx_list_part_t  *next;   // 下一个链表节点
};/*ngx_list_part_s 链表容器,该结构体内确定了 ngx_list_part_s 的存储空间容量、内存管理入口和访问入口。
*/
typedef struct { ngx_list_part_t  *last;  //指向链表的最后一个节点。ngx_list_part_t   part;  //链表的首个数组节点。// 限制 ngx_list_part_s elts 中每个数组元素的占用空间的大小size_t            size;  // 限制 ngx_list_part_s elts 中每个数组最大元素数量,一旦分配后是不可更改的ngx_uint_t        nalloc;// //链表中管理内存分配的内存池对象。用户要存放的数据占用的内存都是由 pool 分配的。ngx_pool_t       *pool;  
} ngx_list_t;

接口描述

// 创建新的链表,指定内存池对象,和数组容量(元素个数和每个元素大小)
// 该函数调用后会返回一个链表,该链表内至少有一个数组,不会是空链表的
ngx_list_t *ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size);// 初始化已有链表,与 ngx_list_create 使用方法相似,其实 ngx_list_create 里面也会调用 ngx_list_init
static ngx_inline ngx_int_t
ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size)// 往链表中新增元素,传入链表,返回新元素的首地址供使用。注意此时返回的是 ngx_list_part_s 中的 elts 成员
void *ngx_list_push(ngx_list_t *list);

具体实现

ngx_list_create

ngx_list_t *
ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size) //实际上就是为nginx_list_t的part成员创建指定的n*size空间,并且创建了空间sizeof(ngx_list_t)
{ngx_list_t  *list;// 分配 ngx_list_t 大小的内存list = ngx_palloc(pool, sizeof(ngx_list_t));if (list == NULL) {return NULL;}// 对空链表进行初始化if (ngx_list_init(list, pool, n, size) != NGX_OK) {return NULL;}return list;
}

ngx_list_init

static ngx_inline ngx_int_t
ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size)
{// 对链表的首个 ngx_list_part_s 元素中的数组分配内存,大小为 n * size,n 为数组元素个数,size 为数组内每个元素的大小,我们可以看到,这些配置在链表初始化的时候就已经写死了,不可再改变,除非再次初始化list->part.elts = ngx_palloc(pool, n * size); if (list->part.elts == NULL) {return NGX_ERROR;}// 对链表的一些属性进行赋值list->part.nelts = 0;list->part.next = NULL;// 初始化时,链表只有一个节点,所以首节点也是末尾节点list->last = &list->part;list->size = size;list->nalloc = n;list->pool = pool;return NGX_OK;
}

ngx_list_push

// 往链表的末尾节点中新增数组,函数返回可用地址指针
void *
ngx_list_push(ngx_list_t *l)
{void             *elt;ngx_list_part_t  *last;last = l->last;// 判断末尾节点的数组空间是否满了if (last->nelts == l->nalloc) {/* the last part is full, allocate a new list part */// 若末尾节点空间满了,则往链表中新增节点,刷新末尾节点地址last = ngx_palloc(l->pool, sizeof(ngx_list_part_t));if (last == NULL) {return NULL;}last->elts = ngx_palloc(l->pool, l->nalloc * l->size);if (last->elts == NULL) {return NULL;}// 新的末尾节点last->nelts = 0;last->next = NULL;// 刷新末尾节点指针,新节点变为末尾节点l->last->next = last;l->last = last;}elt = (char *) last->elts + l->size * last->nelts;last->nelts++;return elt;
}

使用案例

// 创建一个链表,链表中每个数组长度限制为 4,每个数组元素数据类型为 ngx_str_t
// 创建链表的时候,内部会调用 ngx_list_init
ngx_list_t* testlist = ngx_list_create(r->pool, 4, sizeof(ngx_str_t));
if (testlist == null )
{return NGX_ERORR;
}// 往链表中添加数据,该数据会添加到链表末尾节点的数组中,若该数组剩余容量不足,会往链表中新增节点
ngx_str_t* str = ngx_list_push(testlist);
if ( str == null )
{return NGX_ERROR;
}
str->len = sizeof("hello world");
str->value = "he11o world";// 遍历链表
// part 用于指向链表中的每一个 ngx_list_part_t 数组,刚开始执行链表中第一个节点
ngx_list_part_t* part = &testlist.part;
//根据链表中的数据类型,把数组里的 elts 转化为该类型使用
ngx_str_t* str = part->elts;
// i 表示元素在链表的每个 ngx_list_part_t 数组里的序号
for (i ; 0; /* void */; i++)
{// 如果数组已使用的数组元素已经遍历完,则需要跳转到链表中下一个节点if ( i >= part->nelts ){if ( part -> next == NULL ){// 如果某个 ngx_list_part_t 数组的 next 指针为空// 则说明已经遍历完链表了break;}// 访问下一个 ngx_list_part_tpart = part->next;header = part->elts;// 将 i 序号置为 0,准备重新访问下一个数组i = 0;}// 遍历每个链表节点数组内的元素printf("list element : %*s\n", str[i].len, str[i].data);
}

------------------------------------以下为废话,不需要再阅读------------------------------------------

NGINX是一款高性能的HTTP服务器和反向代理服务器,它以其稳定性、丰富的功能集、以及轻量级架构而闻名。在互联网技术栈中,NGINX扮演着至关重要的角色,广泛应用于负载均衡、静态内容服务以及作为反向代理来提高应用的可用性和扩展性。它的事件驱动架构使其能够支持高并发连接,处理大量请求而不显著增加延迟。

NGINX的配置文件采用简洁明了的语法,使得用户可以轻松地进行性能调优和功能定制。通过模块化设计,NGINX不仅支持HTTP/2协议,还提供了对TLS/SSL的全面支持,确保数据传输的安全性。此外,它还具备WebSocket支持,使得实时通信应用能够无缝运行。

NGINX的反向代理能力尤为突出,它可以根据URL路径、头部信息等多种规则将客户端请求智能地转发到后端服务器群中的某一台或多台服务器上,实现请求的高效分发。同时,NGINX还支持健康检查机制,能够自动剔除故障节点,保证服务的高可用性。

对于静态内容的高效处理也是NGINX的一大亮点。它可以快速响应并交付HTML页面、图片、CSS文件等静态资源,极大地提升了网站访问速度。结合其缓存机制,NGINX能有效减轻后端服务器的压力,优化整体系统性能。

NGINX还提供了丰富的第三方模块,如安全防护、流量控制等,进一步增强了其功能性。无论是小型网站还是大型企业级应用,NGINX都能提供灵活且强大的解决方案,是现代Web架构中不可或缺的组成部分。

NGINX是一款高性能的HTTP服务器和反向代理服务器,它以其稳定性、丰富的功能集、以及轻量级架构而闻名。在互联网技术栈中,NGINX扮演着至关重要的角色,广泛应用于负载均衡、静态内容服务以及作为反向代理来提高应用的可用性和扩展性。它的事件驱动架构使其能够支持高并发连接,处理大量请求而不显著增加延迟。

NGINX的配置文件采用简洁明了的语法,使得用户可以轻松地进行性能调优和功能定制。通过模块化设计,NGINX不仅支持HTTP/2协议,还提供了对TLS/SSL的全面支持,确保数据传输的安全性。此外,它还具备WebSocket支持,使得实时通信应用能够无缝运行。

NGINX的反向代理能力尤为突出,它可以根据URL路径、头部信息等多种规则将客户端请求智能地转发到后端服务器群中的某一台或多台服务器上,实现请求的高效分发。同时,NGINX还支持健康检查机制,能够自动剔除故障节点,保证服务的高可用性。

对于静态内容的高效处理也是NGINX的一大亮点。它可以快速响应并交付HTML页面、图片、CSS文件等静态资源,极大地提升了网站访问速度。结合其缓存机制,NGINX能有效减轻后端服务器的压力,优化整体系统性能。

NGINX还提供了丰富的第三方模块,如安全防护、流量控制等,进一步增强了其功能性。无论是小型网站还是大型企业级应用,NGINX都能提供灵活且强大的解决方案,是现代Web架构中不可或缺的组成部分。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/64070.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件项目需求分析的实践探索(1)

一、项目启动与规划 组建团队 包括项目经理、系统分析师、业务分析师以及可能涉及的最终用户代表和领域专家等。例如,开发一个医疗管理软件,就需要有医疗行业的专家参与,确保对医疗业务流程有深入理解。明确各成员的职责,如系统分…

网络管理-期末项目(附源码)

环境:网络管理 主机资源监控系统项目搭建 (保姆级教程 建议点赞 收藏)_搭建网络版信息管理系统-CSDN博客 效果图 下面3个文件的项目目录(python3.8.8的虚拟环境) D:\py_siqintu\myproject5\Scripts\mytest.py D:\py_siqintu\myproject5\Sc…

MySQL 常用程序介绍

以下是一些常用的MySQL程序: 程序名作⽤mysqldMySQL的守护进程即 MySQL 服务器,要使⽤MySQL 服务器 mysqld必须正在运⾏状态mysql MySQL客⼾端程序,⽤于交互式输⼊ SQL 语句或以批处理模式从⽂件执⾏SQL的命令⾏⼯具 mysqlcheck⽤于检查、修…

Redis篇--常见问题篇4--大Key(Big Key,什么是大Key,影响及使用建议)

1、概述 大Key:通常是指值(Value)的长度非常大,实际上键(Key)长度很大也算。通常来说,键本身不会很长,占用的内存较少,因此判断一个键是否为bigKey主要看它对应的值的大…

ModbusTCP从站转Profinet主站案例

一. 案例背景 在复杂的工业自动化场景中,企业常常会采用不同品牌的设备来构建生产系统。西门子SINAMICS G120变频器以其高性能、高精度的速度和转矩控制功能,在电机驱动领域应用广泛。施耐德M580可编程逻辑控制器则以强大的逻辑控制和数据处理能力著称&…

微信小程序-基于Vant Weapp UI 组件库的Area 省市区选择

Area 省市区选择,省市区选择组件通常与 弹出层 组件配合使用。 areaList 格式 areaList 为对象结构,包含 province_list、city_list、county_list 三个 key。 每项以地区码作为 key,省市区名字作为 value。地区码为 6 位数字,前两…

智驾感知「大破局」!新一轮混战开启

随着智能驾驶搭载率的攀升,舱外传感器赛道迎来新变局。 一方面,从近几年智驾传感器的配置变化来看,摄像头的主导地位显而易见。 12月10-12日,由德赛西威总冠名的2024(第八届)高工智能汽车年会暨年度金球奖…

Kibana8.17.0在mac上的安装

1、Kibana是什么 Kibana是与elasticsearch配套使用的数据分析与可视化工具,通过Kibana可以轻松与es中存储的数据进行高效的交互,包括数据写入、检索、删除等操作,并可以通过编写部分代码将数据做成各种报表,从而进行非常直观的统…

数字IC后端设计实现十大精华主题分享

今天小编给大家分享下吾爱IC社区星球上周十大后端精华主题。 Q1:星主,请教个问题,长tree的时候发现这个scan的tree 的skew差不多400p,我高亮了整个tree的schematic,我在想是不是我在这一系列mux前边打断,设置ignore p…

给bmp和png,设置BLENDFUNCTION的AlphaFormat不同参数的效果

BLENDFUNCTION是AlphaBlend用控制透明效果的重要参数。 选择一个32位的png图片,设置AlphaFormat 为 AC_SRC_ALPHA,效果如上图。 选择一个32位的png图片,设置AlphaFormat 为 0,效果如上图。 选择一个24位的bmp图片,设置…

ChildLife“童年时光杯”足球联赛启动 共促青少年健康成长

2024年12月21日至22日,由美国知名婴幼儿营养品牌ChildLife童年时光赞助的“童年时光杯”青少年足球联赛将在上海拉开帷幕。本次赛事U7/U8组别共有16支足球队参赛,包括上海幸运星足球俱乐部旗下的明星球队,以及其他青少年俱乐部的优秀队伍&…

MTK--mt7921 usb wifi debug

文章目录 1、代码编译2、配置文件修改3、Wifi设置命令4、Wifi debug 淘宝随便买个7921的usb wifi。 1、代码编译 export TEMPLATECONF${PWD}/meta/meta-mediatek-mt8518/conf/base/aud8518sp2-slc-32b-7921-c4a-user source meta/poky/oe-init-build-env bitbake mtk-image-au…

如何配置OSB连接数据连接/读取超时

1.Oracle DB OSB中的DBAdapter的查询超时参数配置没用,要解决接口超时问题,需要在console中的数据源配置超时参数: oracle.net.CONNECT_TIMEOUT30000 oracle.net.READ_TIMEOUT30000 添加图片注释,不超过 140 字(可选…

一起学Git【第六节:查看版本差异】

git diff是 Git 版本控制系统中用于展示差异的强大工具。他可以用于查看文件在工作区、暂存区和版本库之间的差异、任意两个指定版本之间的差异和两个分支之间的差异等,接下来进行详细的介绍。 1.显示工作区与暂存区之间的差异 # 显示工作区和暂存区之间的差异,后面不加参数…

Python数据处理——re库与pydantic的使用总结与实战,处理采集到的思科ASA防火墙设备信息

目录 Python正则表达式re库的基本用法 引入re库 各函数功能 总结 使用方法举例 正则表达式语法与书写方式 正则表达式的常用操作符 思科ASA防火墙数据 数据1 数据2 书写正则表达式 Python中pydantic的使用 导入基础数据模板 根据数据采集目标定义Pydantic数据类型…

`we_chat_union_id IS NOT NULL` 和 `we_chat_union_id != ‘‘` 这两个条件之间的区别

文章目录 1、什么是空字符串?2、两个引号之间加上空格 好的,我们来详细解释一下 we_chat_union_id IS NOT NULL 和 we_chat_union_id ! 这两个条件之间的区别,以及它们在 SQL 查询中的作用: 1. we_chat_union_id IS NOT NULL 含…

如何利用AWS监听存储桶并上传到tg bot

业务描述: 需要监听aws的存储中的最新消息,发送新的消息推送到指定tg的频道。 主要流程: 1.上传消息到s3存储桶(不做具体描述) 2.通过aws的lambda监听s3存储桶的最新消息(txt文件) 3.将txt文件…

HarmonyOS NEXT 实战之元服务:静态案例效果---查看国内航班服务

背景: 前几篇学习了元服务,后面几期就让我们开发简单的元服务吧,里面丰富的内容大家自己加,本期案例 仅供参考 先上本期效果图 ,里面图片自行替换 效果图1完整代码案例如下: Index代码 import { authen…

Windows11家庭版启动Hyper-V

Hyper-V 是微软的硬件虚拟化产品,允许在 Windows 上以虚拟机形式运行多个操作系统。每个虚拟机都在虚拟硬件上运行,可以创建虚拟硬盘驱动器、虚拟交换机等虚拟设备。使用虚拟化可以运行需要较旧版本的 Windows 或非 Windows 操作系统的软件,以…

为什么深度学习和神经网络要使用 GPU?

为什么深度学习和神经网络要使用 GPU? 本篇文章的目标是帮助初学者了解 CUDA 是什么,以及它如何与 PyTorch 配合使用,更重要的是,我们为何在神经网络编程中使用 GPU。 图形处理单元 (GPU) 要了解 CUDA,我们需要对图…