nginx 定時器實現詳解

2021-08-17 10:52:32 字數 2894 閱讀 3749

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...