nginx定時器算是nginx乙個重要的功能,nginx的定時器除了實現更新時間的功能之外,還提供了設定處理定時器的功能。而定時器的功能,在nginx中使用非常廣泛。
nginx定時器的實現原理
nginx定時器的實現位於event/ngx_event_timer檔案中,在nginx worker的無間斷loop中不斷對取出定時器,並對其相關的事件進行處理。這裡的事件包含了普通的更新時間的事件和設定的定時器事件。
nginx定時器關鍵的實現結構為紅黑樹,這裡的定時器就是使用時間戳作為key值,將事件資訊掛載在紅黑樹上。在每次的loop中,會不斷地判斷並設定事件的處理延時事件已經超時的事件。
1.nginx新增定時器
//嘗試 inline優化
static ngx_inline void
ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
/*否則 就會刪除之前設定的定時器 */
ngx_del_timer(ev);
}/*設定新的定時器的key值*/
ev->timer.key = key;
ngx_log_debug3(ngx_log_debug_event, ev->log, 0,
"event timer add: %d: %m:%m",
ngx_event_ident(ev->data), timer, ev->timer.key);
/*將新的定時器插入到 紅黑樹中*/
ngx_rbtree_insert(&ngx_event_timer_rbtree, &ev->timer);
//標記這個事件的定時器已經被設定過
ev->timer_set = 1;
}
2.nginx 刪除定時器
//這裡傳入的引數是事件的指標
static ngx_inline void
ngx_event_del_timer(ngx_event_t *ev)
2.nginx 查詢最早的定時器來判斷時間差
ngx_msec_t
ngx_event_find_timer(void)
/*得到紅黑樹的根節點和哨兵節點*/
root = ngx_event_timer_rbtree.root;
sentinel = ngx_event_timer_rbtree.sentinel;
/*找到設定時間最小的定時器節點*/
node = ngx_rbtree_min(root, sentinel);
/*比較當前時間和這個定時器節點中儲存的時間戳
事件戳記錄的是將要處理某個事件的時間點 當然也可能會小於當前的時間戳
*/timer = (ngx_msec_int_t) (node->key - ngx_current_msec);
/*返回的時間差最小值不能超過0 如果為0 意味著事件必須立即進行處理(因為有超時的)
如果大於0 則意味著事件有一段的處理富餘時間
這裡的富餘時間會在呼叫者那裡進行糾正 不會讓富餘的時間超過500ms
*/return (ngx_msec_t) (timer > 0 ? timer : 0);
}
3.nginx處理過期(可能有超時的事件)
void
ngx_event_expire_timers(void)
//找到最小時間戳的定時器
node = ngx_rbtree_min(root, sentinel);
/* node->key > ngx_current_msec */
if ((ngx_msec_int_t) (node->key - ngx_current_msec) > 0)
/*通過節點位址與節點在結構體中的偏移量算出事件的位址(也就是指標)
*/ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer));
ngx_log_debug2(ngx_log_debug_event, ev->log, 0,
"event timer del: %d: %m",
ngx_event_ident(ev->data), ev->timer.key);
/*刪除這個超時的定時器*/
ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
#if (ngx_debug)
ev->timer.left = null;
ev->timer.right = null;
ev->timer.parent = null;
#endif
/*設定沒有設定過定時器*/
ev->timer_set = 0;
/*設定定時器發生超時標誌*/
ev->timedout = 1;
/*交由事件處理函式處理*/
ev->handler(ev);
}}
4.判定紅黑樹中是否存在不可終止(cancel)的定時器
ngx_int_t
ngx_event_no_timers_left(void)
for (node = ngx_rbtree_min(root, sentinel);
node;
node = ngx_rbtree_next(&ngx_event_timer_rbtree, node))
}/* only cancelable timers left */
/*遍歷完成 發現定時器的事件均可終止*/
return ngx_ok;
}
Qt定時器及實現(詳解)
定時器是用來處理週期性事件的一種物件,類似於硬體定時器。例如設定乙個定時器的定時週期為 1000 毫秒,那麼每 1000 毫秒就會發射定時器的 timeout 訊號,在訊號關聯的槽函式裡就可以做相應的處理。qt 中的定時器類是 qtimer。qtimer 不是乙個可見的介面元件,在 ui 設計器的元...
TCP定時器詳解
tcp使用四種定時器 timer,也稱為 計時器 重傳計時器 retransmission timer 堅持計時器 persistent timer 保活計時器 keeplive timer 時間等待計時器 time wait timer。當傳送端收到零視窗的確認時,就啟動堅持計時器,當堅持計時器截...
c 定時器實現
1.setitimer方法 nginx 實現,在這段 中,定義了itimerval的資料結構,並設定這個資料結構的值,從而定時器的間隔時間,settimer的函式第乙個引數表示經過timer就會觸發sigalarm事件,然後註冊了訊號sigalarm的事件,從而觸發定時器 signal sigalr...