nginx源码分析—全局变量ngx_cycle的初始化

来源:互联网 发布:c语言 rand 编辑:程序博客网 时间:2024/04/30 00:16

作者:阿波

链接:http://blog.csdn.net/livelylittlefish/article/details/7247080

Content

0.

1. ngx_cycle_t结构

2. ngx_init_cycle()分析

3.注意问题

3.1如何调用CORE模块的callback函数?

3.2 open_files链表中的文件名何时初始化?

4.小结

 

0.

 

Nginx的大部分初始化工作主要围绕一个类型为ngx_cycle_t类型的全局变量(cycle)展开。本文重点介绍全局变量ngx_cycle的初始化。

实现文件:./src/core/ngx_cycle.c.表示nginx-1.0.4代码目录,本文为/usr/src/nginx-1.0.4

 

1. ngx_cycle_t结构

 

该结构在./src/core/ngx_cycle.h文件中定义,如下。

[cpp] view plaincopy
  1. struct ngx_cycle_s {  
  2.     void                  ****conf_ctx;  //配置上下文数组(含所有模块)  
  3.     ngx_pool_t               *pool;      //内存池  
  4.   
  5.     ngx_log_t                *log;       //日志  
  6.     ngx_log_t                 new_log;  
  7.   
  8.     ngx_connection_t        **files;     //连接文件  
  9.     ngx_connection_t         *free_connections;  //空闲连接  
  10.     ngx_uint_t                free_connection_n; //空闲连接个数  
  11.   
  12.     ngx_queue_t               reusable_connections_queue;  //再利用连接队列  
  13.   
  14.     ngx_array_t               listening;     //监听数组  
  15.     ngx_array_t               pathes;        //路径数组  
  16.     ngx_list_t                open_files;    //打开文件链表  
  17.     ngx_list_t                shared_memory; //共享内存链表  
  18.   
  19.     ngx_uint_t                connection_n;  //连接个数  
  20.     ngx_uint_t                files_n;       //打开文件个数  
  21.   
  22.     ngx_connection_t         *connections;   //连接  
  23.     ngx_event_t              *read_events;   //读事件  
  24.     ngx_event_t              *write_events;  //写事件  
  25.   
  26.     ngx_cycle_t              *old_cycle;     //old cycle指针  
  27.   
  28.     ngx_str_t                 conf_file;     //配置文件  
  29.     ngx_str_t                 conf_param;    //配置参数  
  30.     ngx_str_t                 conf_prefix;   //配置前缀  
  31.     ngx_str_t                 prefix;        //前缀  
  32.     ngx_str_t                 lock_file;     //锁文件  
  33.     ngx_str_t                 hostname;      //主机名  
  34. };  

该结构体的大小是确定的,sizeof(ngx_cycle_t)=224

其中,

  • pathes数组元素结构为ngx_path_t
  • open_files链表元素结构为ngx_open_file_t
  • shared_memory链表元素结构为ngx_shm_zone_t
  • listening数组元素结构为ngx_listening_t,该数组用来存放监听套接字。

各种数据结构关系图如下。

 

2. ngx_init_cycle()分析

初始化过程如下。

  • 调用ngx_timezone_update()更新时区,调用ngx_time_update()更新时间
  • 创建大小为NGX_CYCLE_POOL_SIZE=16384B的内存池,并从中分配ngx_cycle_t结构
  • 简单初始化,如记录pool指针、log指针
  • 初始化配置前缀、前缀、配置文件、配置参数等字符串
  • 初始化pathes数组
  • 初始化open_files链表
  • 初始化shared_memory链表
  • 初始化listening数组
  • 初始化resuable_connections_queue队列
  • poolconf_ctx分配空间
  • 初始化hostname字符串
  • 调用core模块的create_conf()
  • 配置文件解析
  • 调用core模块的init_conf()
  • 遍历open_files链表中的每一个文件并打开
  • 创建共享内存并初始化(新旧shared_memory链表的比较,相同的共享内存保留,旧的不同的共享内存被释放,新的被创建)
  • (尝试5)遍历listening数组并打开所有侦听sockets(socket()->setsockopt()->bind()->listen())
  • 提交新的cycle配置,并调用所有模块的init_module(实际上只有ngx_event_core_module模块定义了该callback,即只有ngx_event_module_init()被调用)
  • 关闭或删除残留在old_cycle中的资源
    • 释放多余的共享内存
    • 关闭多余的侦听sockets
    • 关闭多余的打开文件

具体请参考附录代码,不需要细究每一步实现,重要的是要搞清楚其初始化流程。 

简要的函数调用图如下。图的自动生成,可参考<Graphviz可视化函数调用-使用开源软件来简化复杂调用结构>

初始化过程中全局结构ngx_cycle结构图如下。

main()调用ngx_init_cycle()后,全局变量ngx_cycle的内容如下。可对比上图查看。

[plain] view plaincopy
  1. (gdb) p *ngx_cycle  
  2. $3 = {  
  3.   conf_ctx = 0x6b1060,   
  4.   pool = 0x6b0280,   
  5.   log = 0x6b02e8,   
  6.   new_log = {  
  7.     log_level = 4,   
  8.     file = 0x6b0558,   
  9.     connection = 0,   
  10.     handler = 0,   
  11.     data = 0x0,   
  12.     action = 0x0  
  13.   },   
  14.   files = 0x0,   
  15.   free_connections = 0x0,   
  16.   free_connection_n = 0,   
  17.   reusable_connections_queue = {  
  18.     prev = 0x6b0330,   
  19.     next = 0x6b0330  
  20.   },   
  21.   listening = {  
  22.     elts = 0x6b0930,   
  23.     nelts = 1,   
  24.     size = 184,   
  25.     nalloc = 10,   
  26.     pool = 0x6b0280  
  27.   },   
  28.   pathes = {  
  29.     elts = 0x6b04d8,   
  30.     nelts = 5,   
  31.     size = 8,   
  32.     nalloc = 10,   
  33.     pool = 0x6b0280  
  34.   },   
  35.   open_files = {  
  36.     last = 0x6b0398,   
  37.     part = {  
  38.       elts = 0x6b0528,   
  39.       nelts = 2,   
  40.       next = 0x0  
  41. ---Type <return> to continue, or q <return> to quit---  
  42.     },   
  43.     size = 48,   
  44.     nalloc = 20,   
  45.     pool = 0x6b0280  
  46.   },   
  47.   shared_memory = {  
  48.     last = 0x6b03d0,   
  49.     part = {  
  50.       elts = 0x6b08e8,   
  51.       nelts = 0,   
  52.       next = 0x0  
  53.     },   
  54.     size = 72,   
  55.     nalloc = 1,   
  56.     pool = 0x6b0280  
  57.   },   
  58.   connection_n = 1024,   
  59.   files_n = 0,   
  60.   connections = 0x0,   
  61.   read_events = 0x0,   
  62.   write_events = 0x0,   
  63.   old_cycle = 0x0,   
  64.   conf_file = {  
  65.     len = 32,   
  66.     data = 0x6b04b7 "/usr/local/nginx/conf/nginx.conf"  
  67.   },   
  68.   conf_param = {  
  69.     len = 0,   
  70.     data = 0x6b04d8 "\240{l"  
  71.   },   
  72.   conf_prefix = {  
  73.     len = 22,   
  74.     data = 0x6b0490 "/usr/local/nginx/conf//usr/local/nginx//usr/local/nginx/conf/nginx.conf"  
  75.   },   
  76.   prefix = {  
  77.     len = 17,   
  78.     data = 0x6b04a6 "/usr/local/nginx//usr/local/nginx/conf/nginx.conf"  
  79.   },   
  80.   lock_file = {  
  81. ---Type <return> to continue, or q <return> to quit---  
  82.     len = 33,   
  83.     data = 0x6ccee0 "/usr/local/nginx/logs/nginx.lock.accept"  
  84.   },   
  85.   hostname = {  
  86.     len = 4,   
  87.     data = 0x6b11c0 "yu30"  
  88.   }  
  89. }  

 

3.注意问题

 

3.1如何调用CORE模块的callback函数?

 

即如可调用core模块的create_conf()init_conf()

 

(1) callback定义

file: ./src/core/ngx_conf_file.h

[cpp] view plaincopy
  1. typedef struct {          //定义core模块上下文类型  
  2.     ngx_str_t             name;            //模块名,即ngx_core_module_ctx结构体对象的ngx_string("core")  
  3.     void               *(*create_conf)(ngx_cycle_t *cycle);           //创建配置的callback  
  4.     char               *(*init_conf)(ngx_cycle_t *cycle, void *conf); //初始化配置的callback  
  5. } ngx_core_module_t;  

(2) callback初始化

静态初始化ngx_core_module_ctxngx_core_module结构。在编译期间就已确定CORE模块的callback了。

file: ./src/core/nginx.c

[cpp] view plaincopy
  1. static ngx_core_module_t  ngx_core_module_ctx = {  //定义ngx_core_module模块上下文,改方式属于静态初始化  
  2.     ngx_string("core"),  
  3.     ngx_core_module_create_conf,  
  4.     ngx_core_module_init_conf  
  5. };  
  6.   
  7.   
  8. ngx_module_t  ngx_core_module = {          //定义ngx_core_module模块,也是静态初始化  
  9.     NGX_MODULE_V1,  
  10.     &ngx_core_module_ctx,                  /* module context */  
  11.     ngx_core_commands,                     /* module directives */  
  12.     NGX_CORE_MODULE,                       /* module type */  
  13.     NULL,                                  /* init master */  
  14.     NULL,                                  /* init module */  
  15.     NULL,                                  /* init process */  
  16.     NULL,                                  /* init thread */  
  17.     NULL,                                  /* exit thread */  
  18.     NULL,                                  /* exit process */  
  19.     NULL,                                  /* exit master */  
  20.     NGX_MODULE_V1_PADDING  
  21. };  

静态初始化ngx_core_commands结构。

file: ./src/core/nginx.c

[cpp] view plaincopy
  1. static ngx_command_t  ngx_core_commands[] = {  //静态初始化core模块的命令  
  2.   
  3.     { ngx_string("daemon"),  
  4.       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,  
  5.       ngx_conf_set_flag_slot,  
  6.       0,  
  7.       offsetof(ngx_core_conf_t, daemon),  
  8.       NULL },  
  9.   
  10.     { ngx_string("master_process"),  
  11.       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,  
  12.       ngx_conf_set_flag_slot,  
  13.       0,  
  14.       offsetof(ngx_core_conf_t, master),  
  15.       NULL },  
  16.   
  17.     { ngx_string("timer_resolution"),  
  18.       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,  
  19.       ngx_conf_set_msec_slot,  
  20.       0,  
  21.       offsetof(ngx_core_conf_t, timer_resolution),  
  22.       NULL },  
  23.   
  24.     { ngx_string("pid"),  
  25.       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,  
  26.       ngx_conf_set_str_slot,  
  27.       0,  
  28.       offsetof(ngx_core_conf_t, pid),  
  29.       NULL },  
  30.   
  31.     { ngx_string("lock_file"),  
  32.       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,  
  33.       ngx_conf_set_str_slot,  
  34.       0,  
  35.       offsetof(ngx_core_conf_t, lock_file),  
  36.       NULL },  
  37.   
  38.     { ngx_string("worker_processes"),  
  39.       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,  
  40.       ngx_conf_set_num_slot,  
  41.       0,  
  42.       offsetof(ngx_core_conf_t, worker_processes),  
  43.       NULL },  
  44.   
  45.     /* ... 省略中间的定义 */  
  46.   
  47. #if (NGX_THREADS)  
  48.   
  49.     { ngx_string("worker_threads"),  
  50.       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,  
  51.       ngx_conf_set_num_slot,  
  52.       0,  
  53.       offsetof(ngx_core_conf_t, worker_threads),  
  54.       NULL },  
  55.   
  56.     { ngx_string("thread_stack_size"),  
  57.       NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,  
  58.       ngx_conf_set_size_slot,  
  59.       0,  
  60.       offsetof(ngx_core_conf_t, thread_stack_size),  
  61.       NULL },  
  62.   
  63. #endif  
  64.   
  65.       ngx_null_command  
  66. };  

3.2 open_files链表中的文件名何时初始化?

在初始化open_files链表之后遍历该链表并打开文件之前,并未看到向open_files链表中写入文件名。那么,何时写入open_files链表的?

——在ngx_conf_open_file函数中写入。

具体请参考源代码。打开文件后,open_files链表就保存了ngx_open_file_t结构的数据,具体请参考该结构定义。

4.小结

本文主要分析ngx_cycle的初始化,后文继续分析其中调用的CORE模块的callback和配置文件解析等。

 

Appendix: ngx_init_cycle()代码

省略,可自行研究。


http://blog.csdn.net/livelylittlefish/article/details/7247080

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一岁半的宝宝不听话怎么办 老公是个窝囊废怎么办 幼儿园老师不喜欢家长怎么办 老师讨厌学生了怎么办 一个舍友很讨厌怎么办 家长对老师不满怎么办 教师被家长辱骂怎么办 如果老师喜欢自己怎么办 孩子不思进取逃避学习怎么办 老师拿孩子泄愤怎么办 老师对小孩不好怎么办 孩子被老师骂怎么办 孩子幼儿园被打怎么办 两个家长吵架老师怎么办 家长和老师矛盾怎么办 孩子特别害怕老师怎么办? 老师排挤孤立孩子怎么办 很害怕一件事怎么办 高中老师误会我怎么办 家长讹老师老师怎么办 小孩子老说头疼怎么办 孩子总是否定自己怎么办 孩子总是否定别人怎么办 老师屏蔽家长该怎么办 初二学生学疲劳怎么办 孩子不愿补英语怎么办 培训班孩子不学怎么办 小孩不想去学校怎么办 讨厌父母的性格怎么办 老师揪孩子耳朵怎么办 老师整天骂孩子怎么办 教师被学生骂怎么办 幼儿园学生骂老师怎么办 学生骂老师外号怎么办 小孩上课很多嘴怎么办 学生老玩手机怎么办 和校长有了矛盾怎么办 家长打了我怎么办 小朋友不想去幼儿园怎么办 小朋友不想上幼儿园怎么办 高中老师打学生家长怎么办