Nginx学习之ngx_cycle_s中的四维指针

nginx数据结构之ngx_cycle_s 数据结构ngx_cycle_s的完整定义 在/nginx/src/core/ngx_cycle.h文件中。 struct ngx_cycle_s {      void                  ****conf_ctx;         //配置上下文数组,包含所有模块的config_t, 如core模块,则为:ngx_core_conf_t信息      ngx_pool_t 阅读详情

        好记性不如烂笔头!刚开始看完一遍nginx的源码,由于源码工程量比较大,看完之后理解了,过一段时间再回过头来看又有点遗忘。所以决定做一下记录,以便后续翻阅,如有漏错,欢迎指正。

        ngx_cycle_s结构体可以说是Nginx中最为重要的结构体,它贯穿着整个进程代码。本节我就该结构中的 void ****conf_ctx 四级指针进行深入学习。

        Nginx的所有配置结构体全部放在conf_ctx这个四维指针中。下来我们梳理一下源码,主要对HTTP模块所对应的四维指针进行详细分析,其它模块同理,再次就不再做赘述。下来先看一下源码中的ngx_init_cycle函数,主要代码如下:

ngx_cycle_t* ngx_init_cycle(ngx_cycle_t *old_cycle)
{
    ……
	// conf_ctx指针 指向ngx_max_module个 (void *) 指针指向每个模块
    cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
    if (cycle->conf_ctx == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

    ……
	// conf_ctx指针中 modules 二级指针指向 ngx_modules 全局变量
    if (ngx_cycle_modules(cycle) != NGX_OK) {
        ngx_destroy_pool(pool);
        return NULL;
    }

	// 只有core模块才有create_conf, init_conf结构
    for (i = 0; cycle->modules[i]; i++) {
        if (cycle->modules[i]->type != NGX_CORE_MODULE) {
            continue;
        }

		// 指向各CORE模块的 module context
		// 对应http模块来说指向&ngx_http_module_ctx
        module = cycle->modules[i]->ctx;

        if (module->create_conf) {
            rv = module->create_conf(cycle);
            if (rv == NULL) {
                ngx_destroy_pool(pool);
                return NULL;
            }

			// 每个模块create_conf返回 void * 对应的 conf_ctx[i] 中
            cycle->conf_ctx[cycle->modules[i]->index] = rv;
        }
    }
	……

	// conf的ctx指向cycle中的四维指针conf_ctx
    conf.ctx = cycle->conf_ctx;
    conf.cycle = cycle;
    conf.pool = pool;
    conf.log = log;
    conf.module_type = NGX_CORE_MODULE;
    conf.cmd_type = NGX_MAIN_CONF;
	……
	
	// 解析配置文件
    if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
        environ = senv;
        ngx_destroy_cycle_pools(&conf);
        return NULL;
    }
	……
}

        上述代码实现的conf_ctx这个四维指针中的其中两维。

        1、一维是申请并指向所有模块(ngx_max_module个 (void *) 指针)的配置,而并非所有主模块的配置。

        2、二维指向对应主模块的create_conf函数(只有ngx_core_module模块该函数指针不为NULL)所返回的内存。对应http模块则对应的create_conf为NULL,因此它的二维目前指的为NULL。

        结合上述代码的后半段及以下代码分析,ngx_conf_handler函数是ngx_conf_parse解析配置文件时调用的。主要代码如下:

static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
{
	……
	if (cmd->type & NGX_DIRECT_CONF)     // 主模块 ngx_core_commands 中命令
    {
		conf = ((void **) cf->ctx)[cf->cycle->modules[i]->index];
	} 
    else if (cmd->type & NGX_MAIN_CONF)   // 子模块event、http、mail 中命令
    {
		conf = &(((void **) cf->ctx)[cf->cycle->modules[i]->index]);
	} 
    else if (cf->ctx)
    {
		confp = *(void **) ((char *) cf->ctx + cmd->conf);

		if (confp) {
			conf = confp[cf->cycle->modules[i]->ctx_index];
		}
	}
	
    // 调用对应命令的set回调函数
	rv = cmd->set(cf, cmd, conf);
	……
}

        上述代码中cf->ctx指向cycle中的四维指针conf_ctx;上述我们已将思维指针的其中二维已经分析即:所有模块的一维指针已初始化,ngx_core_module模块的二维指针已初始化(其他event、http、mail 对应的create_conf函数指针都为NULL)。

        下来分析ngx_conf_handler函数。因为 http命令字的type为 :NGX_MAIN_CONF,因此当遇到http{}关键字时,对应会执行:conf =&(((void **) cf->ctx)[cf->cycle->modules[i]->index]),我们下来分析一下该语句。

        当命令类型为 NGX_DIRECT_CONF 时,说明该命令为 ngx_core_module 模块命令,因为ngx_core_module 模块有 create_conf 函数,此时:conf_ctx中的一维指针中的 void* 已经通过core模块的create_conf函数申请了空间,所以只需将conf指针指向申请的空间就行。对应执行:conf = ((void **) cf->ctx)[cf->cycle->modules[i]->index]。

        当命令类型为 NGX_MAIN_CONF时,对应所以的子模块(event、http、mail)都没有实现create_conf函数,因此需取出void*的地址来通过各自模块的ngx_xxx_block函数为其申请空间。对应执行:conf = &((void **) cf->ctx)[cf->cycle->modules[i]->index]。

        然后将conf指针作为cmd->set()函数的回调函数的参数并执行。对于http命令来说将调用nginx_http_block函数,主要代码如下:

static char * ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
	……
    if (*(ngx_http_conf_ctx_t **) conf) {
        return "is duplicate";
    }

    // 申请 ngx_http_conf_ctx_t 结构的内存
    ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
    if (ctx == NULL) {
        return NGX_CONF_ERROR;
    }

    // *conf 实质等于 数组申请的 void*
    *(ngx_http_conf_ctx_t **) conf = ctx;

    // 以下3个ngx_pcalloc申请 ngx_http_conf_ctx_t 结构中的三个二维指针内存
    ctx->main_conf = ngx_pcalloc(cf->pool,
                                 sizeof(void *) * ngx_http_max_module);
    if (ctx->main_conf == NULL) {
        return NGX_CONF_ERROR;
    }

    ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
    if (ctx->srv_conf == NULL) {
        return NGX_CONF_ERROR;
    }

    ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
    if (ctx->loc_conf == NULL) {
        return NGX_CONF_ERROR;
    }

    // 调用对应http模块的create_main_conf、create_srv_conf、create_loc_conf函数
    for (m = 0; cf->cycle->modules[m]; m++) {
        if (cf->cycle->modules[m]->type != NGX_HTTP_MODULE) {
            continue;
        }

        module = cf->cycle->modules[m]->ctx;
        mi = cf->cycle->modules[m]->ctx_index;

        if (module->create_main_conf) {
            ctx->main_conf[mi] = module->create_main_conf(cf);
            if (ctx->main_conf[mi] == NULL) {
                return NGX_CONF_ERROR;
            }
        }

        if (module->create_srv_conf) {
            ctx->srv_conf[mi] = module->create_srv_conf(cf);
            if (ctx->srv_conf[mi] == NULL) {
                return NGX_CONF_ERROR;
            }
        }

        if (module->create_loc_conf) {
            ctx->loc_conf[mi] = module->create_loc_conf(cf);
            if (ctx->loc_conf[mi] == NULL) {
                return NGX_CONF_ERROR;
            }
        }
    }
    ……
}

        如上代码,对应http模块来说,它的二维指针指向的结构为:ngx_http_conf_ctx_t;该结构中有三个 void** 类型的指针;对于main_conf、srv_conf、loc_conf三个void**指针申请内存为: ngx_http_max_module个void*的大小;因此http模块的三维指针对应:main_conf、srv_conf、loc_conf类型的指针。因为这三个指针每一个都是二维指针(void**),指向的一个void* 的数组,对于main_conf指针来说指向对应http模块的create_main_conf函数返回的地址,因此http模块的四维指针对应的是create_xxx_conf函数返回的地址。执行srv_conf、loc_conf指针同理在此不再赘述,下来看一下 http 的第一个模块ngx_http_core_module 的 create_main_conf 函数,主要代码如下:

static void * ngx_http_core_create_main_conf(ngx_conf_t *cf)
{
    ngx_http_core_main_conf_t  *cmcf;

    cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t));
    if (cmcf == NULL) {
        return NULL;
    }
    ……

    return cmcf;
}

        以上对四维指针详细的分析了,其实对于四维指针只有http模块用了四维;对于ngx_core_module 模块只用了二维指针,源代码其实实现的非常清楚。下来我通过一张图片对本节进行一下整体梳理,梳理图如下:

nginx 网络框架浅析 文章目录nginx 事件驱动框架浅析nginx主循环框架 ngx_cycle_snginx事件 ngx_event_snginx连接 ngx_connection_snginx事件模块 ngx_event_module_sepoll事件模块 ngx_epoll_modulenginx 对过期事件的处理定时器事件nginx惊群处理和负载均衡算法惊群效应和负载不均衡的由来惊群的处理负载均衡算法 ngi... 阅读详情

相关推荐

Nginx 源码阅读笔记5 初始化 cycle

距离上一篇过了有一个多星期,虽然没有写总结笔记,但是一直有在看代码,目前看完了 http 的发送,感兴趣的只剩下 subrequest 和 upstream 部分了,不得不说啊,这个异步的代码,看起来真的是难受,还有就是前几天发布了1.12.0版本,而我在看得是1.10.3版本,虽然没什么大问题,但是强迫症告诉我要看新的,于是搞了很久的diff和patch,由于代码中含注释太多,打起补丁来太麻烦了,

丶Hiroshi 819

nginx中ngx_cycle_s的conf_ctx初始化

nginx中ngx_cycle_s的conf_ctx初始化

多看多听多总结 1134

Nginx源码剖析--ngx_cycle_s结构体分析

前言Nginx框架是围绕着ngx_cycle_t结构体运行的。ngx_cycle_t结构体中包含的信息主要可以分为以下部分: 所有模块的配置信息 Nginx运行时所需要的一些资源,包括连接池,内存池,打开文件,操作目录等等 本文将详细介绍ngx_cycle_t结构体所包含的内容。ngx_cycle_t结构体的内容struct ngx_cycle_s { //保存所有模块的配置结构体

Swartz2015的专栏 1603

ngx_cycle_s

ngx_cycle_sngx_cycle_s结构体typedef ngx_cycle_s ngx_cycle_t;struct ngx_cycle_s { /* 保存着所有模块存储配置项的结构体指针,它首先是一个数组,每个数组成员又是一个指针, 这个指针指向另一个存储着指针的数组 */ void ****conf_ctx; //内存池

猫和鱼爪的鸟窝 1000

Qwen3-Omni-30B-A3B-Instruct微调指南:如何打造专属智能博物官(附数据集)

本文详细介绍了如何对Qwen3-Omni-30B-A3B-Instruct模型进行微调,以打造专业的智能博物官。指南涵盖了从理解模型架构优势、构建高质量文博数据集,到使用LLaMA-Factory进行实战微调、效果评估与部署优化的完整流程,并提供了关键的环境配置与性能优化建议,帮助开发者在垂直领域高效定制专属AI助手。

weixin_29096377的博客 1143

Redis【实战篇】---- 分布式锁-redission

重入问题:重入问题是指 获得锁的线程可以再次进入到相同的锁的代码块中,可重入锁的意义在于防止死锁,比如HashTable这样的代码中,他的方法都是使用synchronized修饰的,假如他在一个方法内,调用另一个方法,那么此时如果是不可重入的,不就死锁了吗?所以可重入锁他的主要意义是防止死锁,我们的synchronized和Lock锁都是可重入的。不可重试:是指目前的分布式只能尝试一次,我们认为合理的情况是:当线程在获得锁失败后,他应该能再次尝试获得锁。

是微风,是晚霞,是无可替代 1万+

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_cycle_t 类型

定义在 src/core/ngx_core.h。

weixin_41812346的博客 771

Zotero on Mac: 高效文献管理与引用指南

本文为Mac用户提供了一份全面的Zotero高效文献管理与引用指南。从安装配置、文献收集管理、PDF深度阅读与笔记,到在Word中无缝插入引用和生成参考文献,详细讲解了核心工作流。同时推荐了ZotFile、Better BibTeX等必备插件,并介绍了利用同步与WebDAV实现跨设备无缝衔接的方法,助力研究者构建个人数字知识库,极大提升学术研究效率。

weixin_29281941的博客 1177

nginx中的几个主要结构体:ngx_cycle_t,ngx_listening_t,ngx_connection_t和ngx_peer_connection_t...

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34279579的博客 702

最新,弱小目标检测数据集,持续更新中。

梳理了最新的下弱小目标检测数据库,方便后续开发使用

weixin_43331421的博客 4095

使用Tansformer分割三维腹部多器官--UNETR实战

不会 transformer 没关系,本教程开箱即用。Tina姐总算对transformer下手了,之前觉得难,因为刚开始学序列模型的时候就没学会。然后就一直排斥学transformer。这两周没什么事,加上MONAI有现成的教程,就打算先跑通后,再学理论。然后,顺利的跑通了代码,再学了一周理论,发现它也不过如此嘛,入门还是很容易的。有同学想了解的transformer的话,可以先看完这个实战教程,如果感兴趣,后续会出一个transformer入门路线。利用纯Transformers作为编码器来学习输入量的

Tina姐的博客 1万+

nginx共享内存原理和源码分析

简介 nginx 共享内存是利用 mmap 将内容存储在内存中以及自旋锁。当 master 启动的时候, 根据相应的指令去初始化共享内存。利用共享内存实现一个轻量级的 k/v 系统。 全局变量 ngx_cycle_s 结构 struct ngx_cycle_s { void ****conf_ctx; //配置上下文数组(含所有模块) ngx_pool_t *pool; //内存池 ngx_log_t *log; //日志 ngx_log_t new_log; ngx_conne

focus on security 1892

中台战略-第五章、中台建设方法论

文章目录第五章、中台建设方法论5.1 中台架构整体策略5.2 业务顶层设计5.3 业务中台设计方法论5.3.1 能力支撑是基础5.3.2 中心自治是承载形式5.3.3 3层模型是骨架5.3.4 5步法是指导思想1. 业务抽象2. 高阶设计3. 组件建模4. 开发交付5. 持续运营5.4 数据中台设计方法论5.4.1 总体规划5.4.2 数据集成5.4.3 模型建设5.4.4 通用研发5.4.5 资产管理5.4.6 数据服务5.5 应用向中台迁移的3中途径和方法5.5.1 方法1:新应用替换旧应用5.5.2

沧海之巅的专栏 1461

nginx源码分析-ngx_cycle_s结构说明

ngx_cycle_s数据结构: struct ngx_cycle_s { void ****conf_ctx; //配置上下文数组,包含所有模块的config_t, 如core模块,则为:ngx_core_conf_t信息 ngx_pool_t *pool; //内存池

@农夫(Ben.Liang) 1878

哨兵1号回波数据(L0级)FDBAQ压缩算法详解

本文介绍哨兵1号用的FDBAQ算法,它实现非整数可变bit压缩,大部分数据仅需 3bit输出,少数高反射率数据需4bit输出,使得平均输出比特率刚超过3bit,比熵约束分块自适应量化 (ECBAQ)压缩算法所需的3.7bit更低。也就是说FDBAQ压缩完,除了要记录分块尺寸和各块的均值码(对应哨兵1号数据包里的THIDX)外,还需要记录霍夫曼码字的长度(对应哨兵1号数据包里的BRC)。唯一不同的就是量化后的编码规则使用了霍夫曼编码,相当于在传统的BAQ压缩流程的后面又加了一个步骤。

2302

C++ PCL点云处理实战专栏

工业级点云处理技术学习资源,涵盖电力、建筑、隧道等领域的实战案例。内容分为三阶段:代码原理(算法认知)、动态库(项目验证)和完整代码(定制开发)。

weixin_45196569的博客 1117

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

nginx源码分析 nginx-1.11.1 参考书籍《深入理解nginx模块开发与架构解析》 核心数据结构与内存池概述 在Nginx中的核心数据结构就是ngx_cycle_t结构,在初始化的过程中就首先初始化了ngx_cycle_t结构,无论是master或者worker进程都初始化了该结构,本文就会分析该结构中的相关作用与成员;本文也会对Nginx的内存管理进行相关的分析,Nginx的内存管...

qq_33339479的博客 614

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

nginx 源码学习笔记(十四)—— 全局变量ngx_cycle

再打算正式开始研究core模块式,发现有一个很重要的变量ngx_cycle_t,一直伴随,如果不懂ngx_cycle可能读起代码来回非常困难,这里就来详细学习一下吧。本文大部分灵感来自于。http://blog.youkuaiyun.com/livelylittlefish/article/details/7247080和http://blog.sina.com.cn/s/blog_677be95b0100i...

数据库天地 274

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

nginx中的四级指针(详解)

https://blog.youkuaiyun.com/brainkick/article/details/7554206 https://www.cnblogs.com/chengxuyuancc/p/3792258.html https://www.cnblogs.com/my_life/articles/5239028.html ngx_events_block : //二级指针...

happylzs2008的专栏 990

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

【nginx流程分析之初始化cycle】

【nginx流程分析之初始化cycle】

qq_37674060的博客 4102

nginx 四级指针 void ****conf_ctx 解析

在c中void*既可以赋值给任何指针,也可以被任何指针赋值。 在c++中void*可以接收所有类型的指针,但是反之不可。 struct ngx_cycle_s { void ****conf_ctx; } if (cmd->type & NGX_DIRECT_CONF) { ...

A_Do_Be的专栏 520

C语言之数组指针

回顾: 数组的名字是数组的首地址,是第 0 个元素的地址,是个常量,数组名字加 1 指向下个元素 二维数组 a 中 ,a+1 指向下个元素,即下一个一维数组,即下一行。a 是数组的名字,是 a[0]的地址,p=a 即 p 保存了 a[0]的地址,即 a 和 p 都指向 a[0],所以在引用数组 元素的时候,a 和 p 等价。a+1 跳一个整型元素,是 a[1]的地址 a 和 a+1 相差一个元素,4 个字节 &a 就变成了一个一维数组指针,是 int(*p)[10]类型的。二维数组,有行,有列。

qq_69748833的博客 499

ngx_cycle_modules

将全局模块数组 ngx_modules 拷贝到 cycle->modules。返回 NGX_OK,代表 成功。

weixin_41812346的博客 306

nginx cycle

   在系统整个运行过程中,需要使用的一些参数、资源需要统一的管理,nginx把这个任务交给了ngx_cycle_t struct ngx_cycle_s { void ****conf_ctx; //指向模块的配置 ngx_pool_t *pool; //内存池 ngx_log_t *log;

benbendy1984的专栏 2692

nginx源码分析三----高级数据结构

一、 与框架相关 ngx_cycle_t struct ngx_cycle_s { //保存存储所有模块的配置项的结构体指针 //之所以是4级指针,是因为conf_ctx首先是一个数组 //然后存储的元素是指针,该指针又指向另外一个指针数组 void ****conf_ctx; //内存池 ngx_pool_t *pool; /* 在还...

qq_26312651的博客 388

Nginx源码分析 - 主流程篇 - 全局变量cycle初始化(11)

Nginx的大部分初始化工作主要围绕一个类型为ngx_cycle_t类型的全局变量(cycle)展开。本文主要讲解cycle的数据结构以及初始化过程中干了什么事情。 cycle的初始化过程在/src/core/cycle.c文件中。 数据结构 ngx_cycle_t的数据结构 /** * Nginx全局变量cycle */ struct ngx_cycle_s { void

自娱自乐的代码人 1万+
上一篇: Nginx学习之内存管理
下一篇: zstd压缩与lz4压缩比较
码农诗人
博客等级 码龄11年 987粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值