step 1
ngx_debug_init(); //linux下为空函数
step 2
if (ngx_strerror_init() != NGX_OK) {
return 1;
return 1;
}
NGX_SYS_NERR,定义在/home/nginx-1.4.4/objs/ngx_auto_config.h,
configure的时候自动生成,生成的办法待研究
debian下的大小为:
static ngx_str_t *ngx_sys_errlist;//指向一个NGX_SYS_NERR * sizeof(ngx_str_t);大小的内存
//遍历NGX_SYS_NERR这么多个err
for (err = 0; err < NGX_SYS_NERR; err++) {
msg = strerror(err); //strerror()用来翻译错误码的宏定义的意思
len = ngx_strlen(msg);
p = malloc(len);
if (p == NULL) {
goto failed;
}
ngx_memcpy(p, msg, len); //开一块内存,将错误码对应的意思拷贝进去
msg = strerror(err); //strerror()用来翻译错误码的宏定义的意思
len = ngx_strlen(msg);
p = malloc(len);
if (p == NULL) {
goto failed;
}
ngx_memcpy(p, msg, len); //开一块内存,将错误码对应的意思拷贝进去
//将以错误码为下标的元素赋值,之后通过错误码可以直接和错误意思对应
ngx_sys_errlist[err].len = len;
ngx_sys_errlist[err].data = p;
}
ngx_sys_errlist[err].len = len;
ngx_sys_errlist[err].data = p;
}
step 3
if (ngx_get_options(argc, argv) != NGX_OK) {
return 1;
}
return 1;
}
初始化各环境变量(全局变量)
step 4
ngx_time_init();
服务器时间的初始化,不明觉厉,需要看到后面再回来研究。
step 5
#if (NGX_PCRE)
ngx_regex_init();
#endif
ngx_regex_init();
#endif
正则初始化,
不明觉厉,需要看到后面再回来研究。
step 6
ngx_pid = ngx_getpid();
取得目前进程的进程pid
step 7
log = ngx_log_init(ngx_prefix);
if (log == NULL) {
return 1;
}
if (log == NULL) {
return 1;
}
日志初始化,日志模块后面会单独开辟一章来分析,先留空。
step 8
#if (NGX_OPENSSL)
ngx_ssl_init(log);
#endif
ngx_ssl_init(log);
#endif
SSL初始化
step 9
ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
init_cycle.log = log;
ngx_cycle = &init_cycle;
init_cycle.pool = ngx_create_pool(1024, log);
if (init_cycle.pool == NULL) {
return 1;
}
init_cycle.log = log;
ngx_cycle = &init_cycle;
init_cycle.pool = ngx_create_pool(1024, log);
if (init_cycle.pool == NULL) {
return 1;
}
初始化一个类型为ngx_cycle_t的局部变量,初始化该结构的log指针,pool指针
step 10
if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
return 1;
}
return 1;
}
把main函数的argc, argv存在ngx_os_argv、ngx_argc、ngx_argv这三个全局变量里面,
不明觉厉,日后再说。
step 11
if (ngx_process_options(&init_cycle) != NGX_OK) {
return 1;
}
return 1;
}
初始化
ngx_cycle结构体
的
prefix, conf_prefix, conf_file, conf_param
等字段
初始化这些结构体变量是根据ngx_prefix、ngx_conf_file、ngx_conf_params等全局变量来的,而这些全局变量是在ngx_get_options()函数中进行的初始化。
- static u_char *ngx_prefix; /* nginx工作目录,默认为/usr/local/nginx/ */
- static u_char *ngx_conf_file; /* 配置文件 */
- static u_char *ngx_conf_params; /* nginx指令 */
step 12
if (ngx_os_init(log) != NGX_OK) {
return 1;
}
return 1;
}
初始化系统相关变量,如内存页面大小
ngx_pagesize
,
ngx_cacheline_size
,
最大连接数
ngx_max_sockets
等;
ngx_int_t
ngx_os_init(ngx_log_t *log)
{
ngx_uint_t n;
#if (NGX_HAVE_OS_SPECIFIC_INIT)
if (ngx_os_specific_init(log) != NGX_OK) {
return NGX_ERROR;
}
#endif
ngx_init_setproctitle(log);
//返回一分页的大小, 单位为字节(byte). 此为系统的分页大小, 不一定会和硬件分页大小相同.
//在intel x86上为4096 bytes
ngx_pagesize = getpagesize();
//设置cpu cacheline大小,该宏定义在./ngx_auto_config.h:#define NGX_CPU_CACHE_LINE 32
//http://blog.csdn.net/zdl1016/article/details/8882092
ngx_cacheline_size = NGX_CPU_CACHE_LINE;
//每次循环,n折半
for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }
#if (NGX_HAVE_SC_NPROCESSORS_ONLN)
if (ngx_ncpu == 0) {
ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);
}
#endif
if (ngx_ncpu < 1) {
ngx_ncpu = 1;
}
//不明觉厉,根据CPU类型设置ngx_cacheline_size的大小
ngx_cpuinfo();
//RLIMIT_NOFILE参数,获取进程可以打开的最多文件数,APUE II P164.之7.11节
if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
ngx_log_error(NGX_LOG_ALERT, log, errno,
"getrlimit(RLIMIT_NOFILE) failed)");
return NGX_ERROR;
}
//记录能打开的最大文件数到ngx_max_sockets全局变量
ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur;
#if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4)
ngx_inherited_nonblocking = 1;
#else
ngx_inherited_nonblocking = 0;
#endif
//设置random函数的种子
srandom(ngx_time());
return NGX_OK;
}
btw: 关于系统软限制和硬限制的查看方式如下
step 13
if (ngx_crc32_table_init() != NGX_OK) {
return 1;
}
return 1;
}
不明觉厉,需要专门分析。
step 14
if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
return 1;
}
return 1;
}
不明觉厉,需要专门分析。
step 15
ngx_max_module = 0;
for (i = 0; ngx_modules[i]; i++) {
ngx_modules[i]->index = ngx_max_module++;
}
for (i = 0; ngx_modules[i]; i++) {
ngx_modules[i]->index = ngx_max_module++;
}
初始化每个
module
的
index
,并计算module的最大值
ngx_max_module
step 16
cycle = ngx_init_cycle(&init_cycle);
if (cycle == NULL) {
if (ngx_test_config) {
ngx_log_stderr(0, "configuration file %s test failed",
init_cycle.conf_file.data);
}
return 1;
}
if (cycle == NULL) {
if (ngx_test_config) {
ngx_log_stderr(0, "configuration file %s test failed",
init_cycle.conf_file.data);
}
return 1;
}
对
ngx_cycle
结构进行初始化,
重要,需要细看。
step 17
if (ngx_signal) {
return ngx_signal_process(cycle, ngx_signal);
}
return ngx_signal_process(cycle, ngx_signal);
}
若有信号,则处理信号。
step 18
ngx_cycle = cycle;
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
ngx_process = NGX_PROCESS_MASTER;
}
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
ngx_process = NGX_PROCESS_MASTER;
}
step 19
if (ngx_init_signals(cycle->log) != NGX_OK) {
return 1;
}
return 1;
}
该函数根据signals来初始化信号。
signals[ ]的定义在src/os/unix/ngx_process.c中,定义了各种信号的处理函数。
step 20
if (!ngx_inherited && ccf->daemon) {
if (ngx_daemon(cycle->log) != NGX_OK) {
return 1;
}
ngx_daemonized = 1;
}
if (ngx_inherited) {
ngx_daemonized = 1;
}
if (ngx_daemon(cycle->log) != NGX_OK) {
return 1;
}
ngx_daemonized = 1;
}
if (ngx_inherited) {
ngx_daemonized = 1;
}
没看懂,待分析
step 21
if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
return 1;
}
return 1;
}
创建进程记录文件
step 22
if (ngx_process == NGX_PROCESS_SINGLE) {
ngx_single_process_cycle(cycle);
} else {
ngx_master_process_cycle(cycle);
}
ngx_single_process_cycle(cycle);
} else {
ngx_master_process_cycle(cycle);
}
进入进程主循环;
- 若为NGX_PROCESS_SINGLE=1模式,则调用ngx_single_process_cycle()进入进程循环;
- 否则为master-worker模式,调用ngx_master_process_cycle()进入进程循环;