服務器兩種高效的事件處理模式

    服務器一般要處理三類事件:IO事件、信號事件、定時事件。由此產生了兩種事件處理模式:編程

  1. Reactor模式:同步IO模型一般用於實現Reactor模式
  2. Proactor模式:異步IO模型用於實現Proactor模式

1、Reactor模式

    主線程(IO處理單元)只負責監聽文件描述符上是否有事件發生,有的話馬上將該事件通知工做線程(邏輯單元)。除此以外主線程不作任何其餘工做,讀寫數據、接收新的鏈接及處理客戶請求均在工做線程中完成。服務器

    使用同步IO模型epoll_wait實現的Reactor模式的工做流程以下:異步

  1. 主線程往epoll內核事件表中註冊socket上的讀就緒事件。
  2. 主線程調用epoll_wait等待socket上有數據可讀。
  3. 當socket上有數據可讀時,epoll_wait通知主線程。主線程則將socket可讀事件放入請求隊列。
  4. 睡眠在請求隊列上的工做線程被喚醒,它從socket讀取數據,並處理客戶請求,而後往epoll內核事件表中註冊該socket上的寫就緒事件。
  5. 主線程調用epoll_wait等待socket可寫。
  6. 當socket可寫時,epoll_wait通知主線程。主線程將socket可寫事件放入請求隊列。
  7. 睡眠在請求隊列上的某個工做線程被喚醒,它往socket上寫入服務器處理客戶請求的結果。

     全部流程能夠總結以下圖1socket

圖1 Reactor模式函數

工做線程從隊列中取出事件後,將根據事件的類型來決定如何處理該事件,上圖1所示的Reactor模式中,不必區分所謂的「讀工做線程」和「寫工做線程」。固然也能夠分別使用讀寫工做線程,對應大型應用,有時候需求區分不一樣的線程處理不一樣的業務。性能

2、Proactor模式

    與Reactor模式不一樣,Proactor模式將全部IO操做都交給主線程和內核來處理,工做線程僅僅負責業務邏輯。spa

    使用異步IO模型(以aio_read和aio_write爲例)實現的Proactor模式的工做流程以下:線程

  1. 主線程調用aio_read函數向內核註冊socket上的讀完成事件,並告訴內核用戶讀緩衝區的位置,以及讀操做完成時如何通知應用程序(這裏以信號爲例,詳情sigevent的man手冊)
  2. 主線程繼續處理其餘邏輯。
  3. 當socket上的數據被讀入用戶緩衝區後,內核將嚮應用程序發送一個信號,以通知應用程序數據已經可用。
  4. 應用程序預先定義好的信號處理函數選擇一個工做線程來處理客戶請求。工做線程處理完客戶請求以後,調用aio_write函數向內核註冊socket上的寫完成事件,並告訴內核用戶寫緩衝區位置,以及寫操做完成時如何通知應用程序(仍以信號爲例)
  5. 主線程繼續處理其餘邏輯。
  6. 當用戶緩衝區的數據被寫入socket以後,內核將嚮應用程序發送一個信號,以通知應用程序數據已經發送完畢。
  7. 應用程序預先定義好的信號處理函數選擇一個工做線程來作善後處理,好比決定是否關閉socket.

    全部流程能夠總結以下圖2對象

圖2 Proactor模式隊列

    在上圖2中,鏈接socket上的讀寫事件是經過aio_read/aio_write向內核註冊的,所以內核將經過信號嚮應用程序報告鏈接socket上的讀寫事件。因此主線程的epoll_wait僅能檢測監聽socket上的鏈接請求事件,不能用來檢測鏈接socket上的讀寫事件。

3、同步IO模擬Proactor模式

    咱們可使用同步IO模擬出Proactor模式:主線程直接執行數據的讀寫操做,讀寫完成以後,主線程向工做隊列通知這一「完成事件」。工做線程直接獲取讀寫的結果,以後只是對讀寫的結果進行邏輯處理。

    使用同步IO模型(epoll_wait)模擬出的Proactor模式的工做流程以下:

  1. 主線程往epoll內核事件表中註冊socket上的讀就緒事件。
  2. 主線程調用epoll_wait等待socket上有數據可讀。
  3. 當socket上有數據可讀時,epoll_wait通知主線程。主線程從socket循環讀取數據,知道沒有更多數據可讀,而後將讀取到的數據封裝成一個請求對象並插入到請求隊列。
  4. 睡眠在請求隊列上的某個工做線程被喚醒,它得到請求對象並處理客戶請求,而後網epoll內核事件表中註冊socket上的寫就緒事件。
  5. 主線程調用epoll_wait等待socket可寫。
  6. 當socket可寫時,epoll_wait通知主線程。主線程網socket上寫入服務器處理客戶端請求的結果。

     全部流程能夠總結以下圖3

 

圖3 同步IO模擬Proactor模式

    注(本文內容參考 Linux高性能服務器編程——第八章 遊雙著)

相關文章
相關標籤/搜索