nginx學習筆記-事件處理模型
阿新 • • 發佈:2018-12-13
簡介
- 對於一個基本的web伺服器來說,事件通常有三種類型
- 網路事件
- 訊號
- 定時器
訊號的處理
對於nginx來說,有一些特定的訊號,代表著特定的意義。訊號會中斷程式當前的執行狀態,在改變狀態後,繼續執行。如果當前正在執行系統呼叫的時候接收到了訊號,則可能導致系統呼叫失敗,需要重入。在nginx的訊號處理體系中,如果nginx正在等我事件(epoll_wait),這個時候程式接收到訊號,在訊號處理完畢之後,epoll_wait會返回錯誤碼,之後程式可以通過差別這個錯誤碼再次進入epoll_wait呼叫
定時器的處理
由於epoll_wait等等的輪洵函式通常可以設定等待超時時間,所以nginx便藉助這個超時時間來實現定時器。nginx裡面的定時器 事件是放在一顆維護定時器的紅黑樹裡面的,每次在進入epoll_wait等待之前,先從紅黑樹裡面拿到所有定時器事件的最小時間,在計算出還有多久到時定時器的鬧鐘時間之後,將這個timeout設定為epoll_wait的等特超時時間
while(True): for t in run_tasks: t.network_handler() now_time = update_time() timeout = ETERNITY # wait_tasks是一個已經排好序的定時器任務陣列 for t in wait_tasks: if(t.exec_time <= now): t.timeout_handler() else: # 如果定時器時間未到,我們計算一下還剩下多少時間 timeout = t.exec_time - now_time break nevents = poll_function(events, timeout) for i in nevents: task t; if(events[i].type == READ): # 將任務的網路事件處理回撥函式設定為讀處理函式 t.network_handler = read_handler else: # 將任務的網路事件處理回撥函式設定為寫處理函式 t.network_handler = write_handler run_tasks_add(t)