nginx 自己維護了乙個時間,使用者向使用者提供時間,它使用快取時間的機制,這樣避免了頻繁的系統呼叫(gettimeofday),加快處理速度。
但快取時間,又必須要及時更新時間,否則時間將不準確。所以, nginx配套了一系列的措施,減少誤差。
void
ngx_process_events_and_timers(ngx_cycle_t *cycle)
else
(void) ngx_process_events(cycle, timer, flags);
}
先暫時不去理會ngx_timer_resolution,只關注else部分,timer = ngx_event_find_timer(),
該函式返回距離第乙個超時事件還有多久時間,可能為-1,即目前沒有註冊超時事件。
而同時,flags 標記為ngx_update_time,即更新快取時間。
static ngx_int_t
ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
}
timer為epoll_wait等待的最大時間,即epoll_wait返回後,由於flags被設定為ngx_update_time,
因而,呼叫ngx_time_update進行快取時間的更新。
上面帶來了乙個新問題,如果,timer 為-1或者過大,而epoll_wait又沒有獲得可用套接字,那麼,此時,
時間很久得不到更新,導致誤差過大。因而,nginx引入了乙個強制更新的策略。
if (ngx_timer_resolution)
ngx_timer_resolution 為使用者配置的引數值,即ngx_timer_resolution時間過後,必須進行時間的更新,
這樣防止時間長時間的不到更新。timer = -1, 這樣,epoll_wait 會無窮阻塞。
static ngx_int_t
ngx_event_process_init(ngx_cycle_t *cycle)
if (setitimer(itimer_real, &itv, null) == -1) {}
}}
首先註冊乙個訊號(sigalrm)處理函式,然後設定乙個計時器setitimer, 在(timer_resoluiton)時間超時後,
傳送sigalrm事件,那麼事件處理函式究竟完成了乙個什麼樣的功能?
void
ngx_timer_signal_handler(int signo)
僅僅將ngx_event_timer_alarm置1。有乙個知識點:訊號中斷系統呼叫。
因而,sigalrm會中斷epoll_wait的呼叫,epoll_wait返回後,errno設定為eintr。
events = epoll_wait(ep, event_list, (int) nevents, timer);
if (flags & ngx_update_time || ngx_event_timer_alarm)
這裡,ngx_event_timer_alarm已經在訊號處理函式中被設定為1, 因此,會執行時間更新。
既然有強制重新整理策略,為嘛還要第一種策略呢?我覺得是這樣,首先這算是乙個優化措施,而
nginx要保證最少配置即可使用,所以,此配置項可以不用進行配置。不同場景有不同的配置,
頻繁訪問的**,不需要timer_resolution,epoll_wait會迅速返回,時間可以及時更新。
記憶體管理機制
記憶體管理 jvm將記憶體分成三大主要區域 堆,棧,方法區,用來儲存資料。堆 堆中主要儲存引用型別物件,給成員變數分配空間。棧 jvm在執行程式時,在棧中會為每乙個方法都提供儲存空間叫棧幀,用來儲存方法中的區域性變數。方法區 用來儲存jvm載入的位元組碼檔案的資訊 類的資訊 包含類的方法,方法只有乙...
記憶體管理機制
記憶體管理是乙個作業系統必不可少 並且 非常重要的一環 linux 的成功 和它優秀的記憶體管理聯絡非常密切 因為乙個系統的高效性慾穩定性往往決定於它的記憶體管理機制 我項很多人吃過 dos 下 640k 的苦吧 前面我們介紹了 386 保護模式 從今天起我們將在此基礎上 分析 linux 的虛擬儲...
Redux管理機制
redux是乙個獨立專門用於做狀態管理的js庫,不是react外掛程式。作用 集中式管理react應用中多個元件共享的狀態和從後台獲取的資料。使用react redux簡化redux的編碼 使用redux thunk實現redux的非同步編碼 使用redux devtools實現chrome中red...