《深入理解Nginx 模塊開發與架構解析》筆記之定時器

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毫秒
發佈了88 篇原創文章 · 獲贊 9 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章