nginx源码学习(二)ngx_init_cycle(&init_cycle)函数解析

1、以下是我阅读nginx(1.13.2版本)源码的一些心得,个人觉得学一个东西最好学它的思想,学会举一反三。因为互联网的东西实在太多 了。
上一章我对nginx启动流程做了一个大概的描述,这一张我详细进入初始化的核心方法进行探索。文章尾部会附上一张nginx中核心结构体
nginx_cycle_s的图,方便在阅读源代码的时候进行对比和理解。

函数名称:
ngx_cycle_t * ngx_init_cycle(ngx_cycle_t *old_cycle)

     //第一步:声明这些变量,变量的意义在初始化的时候进行说明
    void                *rv;
    char               **senv;
    ngx_uint_t           i, n;
    ngx_log_t           *log;
    ngx_time_t          *tp;
    ngx_conf_t           conf;
    ngx_pool_t          *pool;
    ngx_cycle_t         *cycle, **old;
    ngx_shm_zone_t      *shm_zone, *oshm_zone;
    ngx_list_part_t     *part, *opart;
    ngx_open_file_t     *file;
    ngx_listening_t     *ls, *nls;
    ngx_core_conf_t     *ccf, *old_ccf;
    ngx_core_module_t   *module;
    char                 hostname[NGX_MAXHOSTNAMELEN];

//第二步:开始初始化这些变量把指针赋值给cycle结构体
   
    ngx_timezone_update();
    ngx_time_update(); //调用ngx_timezone_update()更新时区,调用ngx_time_update()更新时间
    pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);//申请一个空间内存池,NGX_CYCLE_POOL_SIZE的值为16*1024
    cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));//从内存池中申请内存存放cycle结构体,这个是核心的结构体
  //这些已经在main函数中获取到的值直接赋值给新的核心结构体cycle,不需要再次去解析
    cycle->pool = pool;
    cycle->log = log;
    cycle->old_cycle = old_cycle;
    cycle->conf_prefix.len = old_cycle->conf_prefix.len;
    cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix);
     cycle->prefix.len = old_cycle->prefix.len;
    cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix);
     cycle->conf_file.len = old_cycle->conf_file.len;
    cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1);
     cycle->conf_param.len = old_cycle->conf_param.len;
    cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param);
     ngx_array_init(&cycle->paths, pool, n, sizeof(ngx_path_t *);//初始化一个大小为n,可动态扩展的数组,cycle的paths用来存储的是路径,比如配置很多配置文件的路径
     ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t);
     ngx_rbtree_init(&cycle->config_dump_rbtree, &cycle->config_dump_sentinel, ngx_str_rbtree_insert_value);//红黑树,平衡二叉树一种,用来坐二分搜索用的
     ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t); //打开文件的list,具体list结构参考:http://blog.csdn.net/chen19870707/article/details/40400719
     ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t);//共享内存的初始化
     ngx_array_init(&cycle->listening, pool, n, sizeof(ngx_listening_t);//连接监听的数组,具体结构附录图
     ngx_queue_init(&cycle->reusable_connections_queue);//队列初始化,这个结构体比较简单就两个属性, prev,next
     cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));//给每个模块都分配一个配置属性指针,后面nginx.conf以及其他配置文件中的配置会放到这里

     
     第三步:for循环初始化核心的module,读取配置文件,给cycle中已经初始化了的变量进行赋值。
     1、函数名称:
     
     ngx_int_t  ngx_cycle_modules(ngx_cycle_t *cycle){
       cycle->modules = ngx_pcalloc(cycle->pool, (ngx_max_module + 1)   * sizeof(ngx_module_t *));//申请内存空间,存放module的结构体
       ngx_memcpy(cycle->modules, ngx_modules,  ngx_modules_n * sizeof(ngx_module_t *));//把全局静态变量的内存信息拷贝过来,这个ngx_modules是在编译的时候确定好的,即你安装的时候指定需要使用的扩展,具体可以查看上一章的内容
       cycle->modules_n = ngx_modules_n; //赋值扩展的数量
     }
     2、核心模块配置信息预处理:
         
 for (i = 0; cycle->modules[i]; i++) {
        if (cycle->modules[i]->type != NGX_CORE_MODULE) {//非核心模块不处理
            continue;
        }

        module = cycle->modules[i]->ctx; //模块的上下文

        if (module->create_conf) {
            rv = module->create_conf(cycle);
            if (rv == NULL) {
                ngx_destroy_pool(pool);
                return NULL;
            }
            cycle->conf_ctx[cycle->modules[i]->index] = rv;
        }
    }
    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;

     3、准备了这些之后就可以解析配置文件了:
if (ngx_conf_param(&conf) != NGX_CONF_OK) {
    environ = senv;
    ngx_destroy_cycle_pools(&conf);
    return NULL;
}

if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
    environ = senv;
    ngx_destroy_cycle_pools(&conf);
    return NULL;
}
     第一个if解析nginx命令行参数’-g’加入的配置。第二个if解析nginx配置文件。好的设计就体现在接口极度简化,模块之间的耦合非常低。这里只使用区区10行完成了配置的解析。在这里,我们先浅尝辄止,具体nginx如何解析配置,我们将在后面的小节做细致的介绍。-g是指在命令行加入临时的配置信息,下一章直接解析ngx_conf_parse的详细实现,分析是如何对配置文件进行解析的。
     
     
     
附图(从网上找的,自己画太麻烦):


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值