nginx之main函数的解读(五)
2014-10-14 10:53
3627 查看
继ngx_get_options之后,接下来的代码是:
现在看下一个函数调用ngx_time_init(),该函数定义在core中的ngx_times.c文件当中
定义在core中的ngx_times.h文件当中是ngx_time_t类型的结构体
里面最后调用了ngx_time_update函数,根据是否需要更新当前缓存时间,如果需要则将时间格式转化成多种。
未完,待续...
if (ngx_show_version) { //ngx_write_stderr 定义在ngx_log.h中的内联函数,想文件中写入信息nginx version //NGX_LINEFEED的定义是\x0a,也就是换行 ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED); //当输入参数中包含了h时,会展示帮助信息 if (ngx_show_help) { ngx_write_stderr( "Usage: nginx [-?hvVtq] [-s signal] [-c filename] " "[-p prefix] [-g directives]" NGX_LINEFEED NGX_LINEFEED "Options:" NGX_LINEFEED " -?,-h : this help" NGX_LINEFEED " -v : show version and exit" NGX_LINEFEED " -V : show version and configure options then exit" NGX_LINEFEED " -t : test configuration and exit" NGX_LINEFEED " -q : suppress non-error messages " "during configuration testing" NGX_LINEFEED " -s signal : send signal to a master process: " "stop, quit, reopen, reload" NGX_LINEFEED #ifdef NGX_PREFIX " -p prefix : set prefix path (default: " NGX_PREFIX ")" NGX_LINEFEED #else " -p prefix : set prefix path (default: NONE)" NGX_LINEFEED #endif " -c filename : set configuration file (default: " NGX_CONF_PATH ")" NGX_LINEFEED " -g directives : set global directives out of configuration " "file" NGX_LINEFEED NGX_LINEFEED ); }这段代码的含义很简单,就是如果用户在启动nginx时 输入了 -h的参数的话,则会显示该字符串,提示用户应该输入何种参数,同时参数的含义是什么,接下来时显示配置信息,个人觉得没什么含义
if (ngx_show_configure) { //向控制台输出该配置信息 ngx_write_stderr( #ifdef NGX_COMPILER "built by " NGX_COMPILER NGX_LINEFEED #endif #if (NGX_SSL) #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME "TLS SNI support enabled" NGX_LINEFEED #else "TLS SNI support disabled" NGX_LINEFEED #endif #endif "configure arguments:" NGX_CONFIGURE NGX_LINEFEED); } if (!ngx_test_config) { return 0; } } ngx_max_sockets=-1;
现在看下一个函数调用ngx_time_init(),该函数定义在core中的ngx_times.c文件当中
void ngx_time_init(void) { //ngx_cached_err_log_time ngx_cached_http_time ngx_cached_http_log_time ngx_cached_http_log_iso8601是一个ngx_str_t的结构体 ngx_cached_err_log_time.len = sizeof("1970/09/28 12:00:00") - 1; ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1; ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1; ngx_cached_http_log_iso8601.len = sizeof("1970-09-28T12:00:00+06:00") - 1; //ngx_cached_time 是ngx_time_t类型的结构体该结构体的定义是在/src/core/nginx_time.h当中 ngx_cached_time = &cached_time[0]; //该函数就在ngx_time.c文件当中 ngx_time_update(); }上述各种诸如ngx_cache_err_log_time和ngx_cache_http_time和ngx_cahce_http_log_iso8601等等都是ngx_str_t的结构体变量,而里面之有一个ngx_cache_time,
定义在core中的ngx_times.h文件当中是ngx_time_t类型的结构体
<pre name="code" class="cpp">//时间更新函数 void ngx_time_update(void) { u_char *p0, *p1, *p2, *p3; //ngx_tm_t是tm的重定义 ngx_tm_t tm, gmt; time_t sec; ngx_uint_t msec; ngx_time_t *tp; struct timeval tv; //ngx_time_lock是ngx_atomic_t类型的数据,而ngx_atomic_t可以认为是一个无符号整数 //ngx_trylock该函数在src/os/unix/ngx_atomic.h文件当中 //该ngx_trylock的操作是要求ngx_time_lock是一个无符号整型,由0变成1成功执行,则为真,否则失败,也就是说该函数只允许一个线程执行,否则容易出现错误 if (!ngx_trylock(&ngx_time_lock)) { return; } //当前并没有线程执行到此,只有一个线程执行该函数 //ngx_gettimeofday是gettimeofday的重定义,获得当前系统时间 ngx_gettimeofday(&tv); sec = tv.tv_sec;//秒的数值 msec = tv.tv_usec / 1000;//毫秒的数值 //ngx_current_msec是一个无符号整型 ngx_current_msec = (ngx_msec_t) sec * 1000 + msec;//当前的毫秒的数值 //cache_time是一个ngx_time_t的数组指针,slot也是一个无符号整型,ngx_time_t类型的结构体该结构体的定义是在/src/core/nginx_time.h当中 //slot是静态变量初始化成0,这样tp也就是ngx_cache_time tp = &cached_time[slot]; //如果缓存中索引是slot中获取的时间的秒数就是当前系统的秒数,则将将缓存中获取的时间微秒数置成他的千分之一,然后进行ngx_time_lock解锁操作 if (tp->sec == sec) { //进入到这里是否可以表示,当前时间不用更新, tp->msec = msec; //ngx_unlock是在src/os/unix/ngx_atomic.h文件中他的操作是将ngx_time_lock指向的内存内容置成0 ngx_unlock(&ngx_time_lock); return; } //执行到这里说明我们需要更新缓存时间 //如果slot达到索引的最大值,则将slot置成0,否则自增1 if (slot == NGX_TIME_SLOTS - 1) { slot = 0; } else { slot++; } //获取缓存时间中的第slot个ngx_time_t结构体 tp = &cached_time[slot]; //将该时间结构体的秒数置成当前系统的秒数,微秒数设置成当前微秒数+秒数*1000的数值 tp->sec = sec; tp->msec = msec; //ngx_gmtime函数就在src/core/ngx_times.c文件当中 //该函数的作用是将sec中的秒数换算成年月日 星期等,也就是换成gmt的时间格式 ngx_gmtime(sec, &gmt); //cache_http_time定义在本文件当中,是u_char类型的二维数组,行是NGX_TIME_SLOTS,列则是需要我们指定的时间格式的长度"Mon, 28 Sep 1970 06:00:00 GMT" p0 = &cached_http_time[slot][0]; //这样的话就将cache_http_time格式化成如下类型的时间格式 (void) ngx_sprintf(p0, "%s, %02d %s %4d %02d:%02d:%02d GMT", week[gmt.ngx_tm_wday], gmt.ngx_tm_mday, months[gmt.ngx_tm_mon - 1], gmt.ngx_tm_year, gmt.ngx_tm_hour, gmt.ngx_tm_min, gmt.ngx_tm_sec); #if (NGX_H***E_GETTIMEZONE) //ngx_gettimezone获得世界时间和当地时间的时间差(以妙计) tp->gmtoff = ngx_gettimezone(); //tp->gmtoff是相差的分钟数,所以应该乘以60获得秒数,考虑到时区的误差,ngx_gmttime将time_t转换成tm数据类型 ngx_gmtime(sec + tp->gmtoff * 60, &tm); #elif (NGX_H***E_GMTOFF) //ngx_local_time是放在src/os/unix/ngx_time.c文件当中的 ngx_localtime(sec, &tm); cached_gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60); tp->gmtoff = cached_gmtoff; #else ngx_localtime(sec, &tm); //ngx_tm_isdst如果是1表示使用夏令时,否则不适用 cached_gmtoff = ngx_timezone(tm.ngx_tm_isdst); tp->gmtoff = cached_gmtoff; #endif //到这里得到了我们最终需要的时间:tm,然后呢,根据需要,将tm转化成我们需要的格式即可 p1 = &cached_err_log_time[slot][0]; //时间格式"1970/09/28 12:00:00" (void) ngx_sprintf(p1, "%4d/%02d/%02d %02d:%02d:%02d", tm.ngx_tm_year, tm.ngx_tm_mon, tm.ngx_tm_mday, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec); // p2 = &cached_http_log_time[slot][0]; //时间格式"28/Sep/1970:12:00:00 +0600" (void) ngx_sprintf(p2, "%02d/%s/%d:%02d:%02d:%02d %c%02d%02d", tm.ngx_tm_mday, months[tm.ngx_tm_mon - 1], tm.ngx_tm_year, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec, tp->gmtoff < 0 ? '-' : '+', ngx_abs(tp->gmtoff / 60), ngx_abs(tp->gmtoff % 60)); p3 = &cached_http_log_iso8601[slot][0]; //时间格式"1970-09-28T12:00:00+06:00" (void) ngx_sprintf(p3, "%4d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d", tm.ngx_tm_year, tm.ngx_tm_mon, tm.ngx_tm_mday, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec, tp->gmtoff < 0 ? '-' : '+', ngx_abs(tp->gmtoff / 60), ngx_abs(tp->gmtoff % 60)); ngx_memory_barrier();//阻止多核处理器进行指令优化 ngx_cached_time = tp; ngx_cached_http_time.data = p0; ngx_cached_err_log_time.data = p1; ngx_cached_http_log_time.data = p2; ngx_cached_http_log_iso8601.data = p3; //ngx_unlock是在src/os/unix/ngx_atomic.h文件中他的操作是将ngx_time_lock指向的内存内容置成0 ngx_unlock(&ngx_time_lock); }当然cahce_time就是ngx_time_t结构体的数组
里面最后调用了ngx_time_update函数,根据是否需要更新当前缓存时间,如果需要则将时间格式转化成多种。
未完,待续...
相关文章推荐
- nginx之main函数的解读(四)
- nginx之main函数的解读(一)
- nginx之main函数的解读(三)
- nginx之main函数的解读(七)
- nginx之main函数的解读(六)
- nginx之main函数的解读(八)
- nginx概念解读
- nginx源码解读之一--开局
- FastDFS的配置、部署与API使用解读(7)Nginx的FastDFS模块
- nginx源码解析一(main函数分析)
- Nginx的配置文件解读
- 基于 Nginx 的软件负载均衡实现解读
- nginx gzip配置参数解读
- nginx第一章--执行main函数前的描述
- Nginx篇--解读nginx配置
- 解读nginx之虚拟主机
- Nginx-解读内置非默认模块 ngx_http_stub_status_module
- nginx中CPU亲和性源码解读
- 解剖Nginx·模块开发篇(5)解读内置非默认模块 ngx_http_stub_status_module
- NGINX----源码阅读一(main函数)