nginx定时器的实现

来源:互联网 发布:图像去水印 python 编辑:程序博客网 时间:2024/06/05 09:37

1.采用缓存数组的方式存储时间
1》虽然nginx现在没有采用多线程的方式,但是他还是考虑到了多线程情况下,一般是这俩种情况(1.多线程的方式2.一个进程在读时间的时候被信号中断,而那个信号里面会更新时间,这样导致读错误)所以nginx就采用了一个数组 cached_time[NGX_TIME_SLOTS];共64个成员,每次ngx_time_update()更新的都是下一个位置的slot,
2》使用数组的另外一个原因是因为为了提高性能希望减少对gettimeofday()的调用,一般来说服务器对时间的精度要求不是很高,但是如果需要精确的时间的话,nginx还提供了一个timer_resolution的指令可以进行设置
2.更新函数的的调用时间:
1》在信号处理中用来更新cached_err_log_time的ngx_time_sigsafe_update()函数,每次执行信号处理函数的时候被调用,
2》ngx_time_update函数
在master进程中,在ngx_master_process_cycle()中,它是被放在sigsuspend()之后,即master捕捉到一个信号并且处理完一个信号的时候进行时间的更新。
worker进程中,ngx_worker_process_cycle()>ngx_process_events_and_timers()->ngx_process_events()中的,对于epoll而言,就是ngx_epoll_process_events(),在该函数中执行epoll_wait()以后就更新一次时间,epoll_wait返回就调用该函数,
3.如何控制时间更新频率:
epoll_wait返回有三种情况,读写事件发生,等到时间超时,事件信号中断,这个时候根据timer_resolution的设置情况分为俩种情况,
第一种是没有设置timer_resolution的时候,它使用定时器红黑树中的最小时间作为epoll_wait的超时时间,
第二种是设置timer_resolution,他会使epoll_wait得超时时间为-1,这表示epoll_wait会一直阻塞直到读写事件发生或信号中断。
ngx_event_process_init(ngx_cycle_t *cycle){
·if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
“setitimer() failed”);
}
该函数中每隔ngx_timer_resolution的时间发出信号ngx_log_alert,执行ngx_timer_signal_handler,该函数把ngx_event_timer_alarm=1
}
ngx_process_events_and_timers(ngx_cycle_t *cycle)
if (ngx_timer_resolution) {
timer = NGX_TIMER_INFINITE;
flags = 0;
} else {
timer = ngx_event_find_timer();
flags = NGX_UPDATE_TIME;
}
ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
events = epoll_wait(ep, event_list, (int) nevents, timer);
err = (events == -1) ? ngx_errno : 0;
if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
ngx_time_update();
}
如果设置了ngx_timer_resolution,那么每隔该时间ngx_event_timer_alarm=1,而后进入该if语句执行时间更新
如果没有设置ngx_timer_resolution,那么timer就是定时器红黑树上面的最小值,那么epoll_wait过了timer以后才返回,而后更新时间。
4.nginx_time_update()
更新时间之前需要获取锁,主要更新的是一下几个变量
ngx_cached_time
ngx_cached_http_time.data
ngx_cached_err_log_time.data
ngx_cached_http_log_time.data

0 0
原创粉丝点击