Nginx 定時器
Nginx 對時間的管理
Nginx爲了提高速度,自己實現了對時間的管理,設計了數據結構和一些變量,存儲在內存中。每一個進程都會單獨地管理當前的時間。
ngx_time_t
typedef struct {
//格林威治時間1970年1月1日凌晨0點0分0秒到當前時間的秒數
time_t sec;
//sec成員只能精確到秒,msec則是當前時間相對sec的毫秒偏移量
ngx_uint_t msec;
//時區
ngx_int_t gmtoff;
} ngx_time_t;
ngx_tm_t
struct tm {
int tm_sec; /* 秒–取值區間爲[0,59] */
int tm_min; /* 分 - 取值區間爲[0,59] */
int tm_hour; /* 時 - 取值區間爲[0,23] */
int tm_mday; /* 一個月中的日期 - 取值區間爲[1,31] */
int tm_mon; /* 月份(從一月開始,0代表一月) - 取值區間爲[0,11] */
int tm_year; /* 年份,其值從1900開始 */
int tm_wday; /* 星期–取值區間爲[0,6],其中0代表星期天,1代表星期一,以此類推 */
int tm_yday; /* 從每年的1月1日開始的天數 - 取值區間爲[0,365],其中0代表1月1日,1代表1月2日,一次類推 */
int tm_isdst; /* 夏令時標識符。在實行夏令時的時候,tm_isdst爲正;不實行夏令時的時候tm_isdst爲0;否則爲負 */
};
typedef struct tm ngx_tm_t;
#define ngx_tm_sec tm_sec
#define ngx_tm_min tm_min
#define ngx_tm_hour tm_hour
#define ngx_tm_mday tm_mday
#define ngx_tm_mon tm_mon
#define ngx_tm_year tm_year
#define ngx_tm_wday tm_wday
#define ngx_tm_isdst tm_isdst
從上面的定義可以看出,ngx_tm_t和struct tm結構是一模一樣的。
Nginx緩存時間的操作函數
函數名 | 參數含義 | 執行意義 |
---|---|---|
void ngx_time_init(void); | 初始化當前進程中緩存的時間變量 | |
void ngx_time_update(void) | 使用gettimeofday調用以系統時間更新緩存的時間 | |
u_char *ngx_http_time(u_char *buf,time_t t) | t是需要轉換的時間(距離格林威治時間的秒數),buf是轉換爲HTTP時間後用來存放字符串的內存 | 將t轉換爲“Mon,28 Sep 1970 06:00:00 GMT”形式 |
u_char *ngx_http_cookie_time(u_char *buf,time_t t) | 同上 | t是需要轉換的時間(距離格林威治時間的秒數),buf是轉換爲HTTP時間後用來存放字符串的內存 |
void ngx_gmtime(time_t t,ngx_tm_t *tp | 將t填充ngx_tm_t | |
time_t ngx_next_time(time_t when) | when表示期待過期的時間,僅表示一天內秒數 | 失敗返回-1;否則返回:1、如果when合併到當前時間後並未超時,那麼返回這個到格林威治時間的秒數;2、如果超時,那麼返回次日同一刻間到格林威治時間的秒數 |
define ngx_time() ngx_cache_time->sec | 獲取格林威治時間到當前時間的秒數 | |
define ngx_timeofday() (ngx_time_t *)ngx_cached_time | 獲取緩存的ngx_time_t類型時間 |
定時器的實現
定時器的結構是一棵紅黑樹。ngx_event_timer_rbtree就是所有定時器組成的紅黑樹,而ngx_event_timer_sentinel就是這棵紅黑樹的哨兵節點。這棵紅黑樹採用關鍵字爲事件的超時時間,因此,最左下角的節點就是最有可能超時的事件。
定時器操作函數
函數名 | 參數含義 | 執行意義 |
---|---|---|
ngx_int_t ngx_event_timer_init(ngx_log_t *log); | 日誌對象 | 初始化定時器 |
ngx_msec_t ngx_event_find_timer(void); | 找出紅黑樹最左下角的節點,如果它比當前時間大,說明沒有準備就緒的事件,返回距離“超時時間”;否則返回0,表示已經有事件準備就緒 | |
void ngx_event_expire_timers(void); | 檢查紅黑樹中的所有事件,調用所有準備就緒事件的handler回調函數 | |
static ngx_inline void ngx_event_del_timer(ngx_event_t *ev); | ev是需要操作的事件 | 從定時器中刪除一個事件 |
static ngx_inline void ngx_event_add_time(ngx_event_t *ev,ngx_msec_t timer) | timer單位是毫秒,它告訴定時器事件ev希望timer毫秒後超時 | 添加一個定時器事件,超時時間爲timer毫秒 |