由于nginx采用的是master-workers多进程的方式,每个一进程都会自己维护一个时间缓存。那么在nginx中什么时候会更新时间缓存呢?上面说到nginx采用了2种方式来维护时间,首先来介绍没有用timer_resolution指令设置时间精度的情况,也就是ngx_timer_resolution为0的情况,实际上只要找一下ngx_time_update()和ngx_time_sigsafe_update()这两个函数被调用的位置就知道。首先来说一下ngx_time_sigsafe_update(),它比较简单只是更新了ngx_cached_err_log_time,它会在每次执行信号处理函数的时候被调用,也就是在ngx_signal_handler()函数中。ngx_time_update()函数在master进程中的ngx_master_process_cycle()主循环中被调用,具体位置为sigsuspend()函数之后,也就是说master进程捕捉到并处理完一个信号返回的时候会更新时间缓存;在worker进程中,ngx_time_update函数的调用链为ngx_worker_process_cycle() -> ngx_process_events_and_timers() -> ngx_process_events() -> ngx_time_update(), 其中ngx_process_events()实际上一个宏,nginx中定义如下:
#define ngx_process_events ngx_event_actions.process_events
而ngx_event_actions为nginx的I/O模型接口函数结构体,封装如epoll, kqueue,select,poll等这些提供的接口,这里仅对epoll进行分析,其他类似,于是ngx_event_actions.process_events 对应ngx_epoll_module.c文件中的 ngx_epoll_process_events()函数,在这个函数中执行epoll_wait()返回后会调用ngx_time_update()更新时间缓存