1. 程式人生 > >nginx學習筆記-事件處理模型

nginx學習筆記-事件處理模型

簡介

  • 對於一個基本的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)