Linux服務器 | 事件處理模式:Reactor模式、Proactor模式

文章目錄

  • Reactor模式
  • Proactor模式
    • 同步I/O模型模擬Proactor模式
  • 兩者的優缺點
    • Reactor
    • Proactor


同步I/O模型通常用于實現 Reactor 模式,異步I/O模型通常用于實現 Proactor 模式。(不是絕對的,同步I/O也可模擬出 Proactor 模式)

Reactor模式

原理

Reactor 模式要求主線程(I/O處理單元)只負責監聽文件描述符上是否有事件就緒,如果有則將該就緒事件通知給工作線程(邏輯單元)。除此之外主線程不會進行其他實質性的工作,讀寫數據、接收新連接、業務邏輯處理全部在工作線程中完成。

工作流程

這里以 epoll_wait 為例,使用同步I/O模型實現的 Reactor 模式的工作流程如下:

  1. 主線程往 epoll 內核事件表中注冊 socket 上的讀就緒事件。
  2. 主線程調用 epoll_wait 開始對 socket 的讀事件進行監控。
  3. 如果 socket 讀就緒,epoll_wait 會通知主線程,主線程則將 socket 可讀事件(即 socket 連接本身) 放入請求隊列中。
  4. 請求隊列上某個休眠的工作線程被喚醒,此時會從 socket 中讀取數據,并且處理用戶請求,然后往 epoll 內核事件表中注冊該 socket 的寫就緒事件。
  5. 主線程繼續調用 epoll_waitsocket 的寫事件進行監控。
  6. socket 寫就緒時,epoll_wait 會通知主線程,主線程則將 socket 可寫事件(即 socket 連接本身) 放入請求隊列中。
  7. 請求隊列上某個休眠的工作線程被喚醒,將服務器處理客戶請求的結果寫入到 socket

在這里插入圖片描述
工作線程從請求隊列中取出事件后,根據事件類型來決定如何處理事件,所以不會區分 讀工作線程寫工作線程


Proactor模式

原理

Proactor模式則是將所有的I/O操作全部交給主線程內核處理工作線程僅僅負責業務邏輯。

工作流程

這里以 aio 為例,使用異步I/O模型實現的 Reactor 模式的工作流程如下:

  1. 主線程調用 aio_read 向內核注冊 socket 上的讀完成事件,并且告訴內核用戶讀緩沖區的位置,以及讀操作完成時如何通知應用程序(這里以信號為例)。
  2. I/O事件交給內核進行異步處理,此時主線程繼續處理其他邏輯(區別于 Reactor 中主線程需要持續監控就緒事件)。
  3. socket 上的數據已被讀入用戶緩沖區后,內核向應用程序發送一個信號,通知其數據已可用。
  4. 通過應用程序預先定義好的信號處理函數來選擇一個工作線程以處理客戶請求。
  5. 工作線程處理完客戶請求之后會調用 aio_write 向內核注冊 socket 上的寫就緒事件,并且告訴內核用戶寫緩沖區的位置,以及寫操作完成時如何通知應用程序(仍選擇使用信號)。
  6. 主線程繼續處理其他邏輯(同2)。
  7. 當用戶緩沖區的數據被寫入 socket 后,內核向應用程序發送一個信號,通知其數據發送完成。
  8. 通過應用程序 注冊(預先定義好) 的信號處理 事件(函數) 來選擇一個工作線程來進行善后處理,例如是否關閉 socket

在這里插入圖片描述

由于讀/寫事件是通過 aio_read/aio_write 向內核中進行 注冊 的,并由內核通過 信號 向應用程序 報告 的。因此,不同于 Reactor 模式,Proactorepoll_wait 僅僅用來監聽 socket 上是否有新的連接請求到來,而不用于 注冊 or 報告 讀/寫事件。


同步I/O模型模擬Proactor模式

原理

主線程執行數據讀寫操作,完成后向工作線程通知事件的完成。從工作線程的角度來看,他們就直接獲得了數據讀寫的結果,接下來的工作就只需要對讀寫結果進行業務邏輯處理。

工作流程

這里以 epoll_wait 為例,使用同步I/O模型實現的 Proactor 模式的工作流程:

  1. 主線程往 epoll 內核事件表中注冊 socket 上的讀就緒事件。(同步I/O注冊就緒事件、異步I/O注冊完成事件)
  2. 主線程調用 epoll_wait 等待 socket 上有數據可讀。
  3. socket 上有數據可讀,epoll_wait 通知主線程,主線程從 socket 中循環讀取數據,直到沒有數據可讀。然后將讀到的數據封裝成一個請求對象插入請求隊列中。
  4. 請求隊列上某個休眠的工作線程被喚醒,此時它會獲取請求對象并且處理客戶請求,然后往 epoll 內核事件表中注冊 socket 的寫就緒事件。
  5. 主線程調用 epoll_wait 等待 socket 可寫。
  6. 如果 socket 寫就緒,epoll_wait 通知主線程,主線程往 socket 中寫入服務器處理客戶請求的結果。

在這里插入圖片描述


兩者的優缺點

Reactor

Reactor 實現了一個被動的事件分離和分發模型:

  • 主線程只負責監聽讀寫事件是否就緒,就緒后放入請求隊列,并喚醒請求隊列上某個工作線程;
  • 工作線程讀寫數據處理客戶請求

優點:

  • 實現相對簡單,對于耗時短的處理場景處理高效。
  • 操作系統可以在多個事件源上等待,并且避免了多線程編程相關的性能開銷和編程復雜性。
  • 事件的串行化對應用是透明的,可以順序的同步執行而不需要加鎖。
  • 將與應用無關的多路分解、分配機制和與應用相關的回調函數分離開來。

缺點:

  • 處理耗時長的操作會造成事件分發的阻塞,影響到后續事件的處理。

適用場景:

同時接收多個服務請求,并且依次同步處理它們的事件驅動程序。


Proactor

Proactor 實現了一個主動的事件分離和分發模型:

  • 主線程監聽事件是否就緒;
  • 內核執行I/O操作讀寫數據;
  • 上一步完成后根據預先注冊好的信號函數選擇一個工作線程處理客戶請求。

優點:

  • 性能更高,能夠適應耗時長的并發場景(各個任務間互不影響);
  • 這種設計允許多個任務并發的執行,從而提高吞吐量。

缺點:

  • 實現邏輯復雜,依賴操作系統對異步的支持,目前實現了純異步操作的操作系統少。
    1. 實現優秀的如 windows IOCP,但由于 windows 系統用于服務器的局限性,目前應用范圍較小。
    2. Unix/Linux 系統對純異步的支持有限,應用事件驅動的主流方案還是通過 select/epoll 來實現。

適用場景:

異步接收同時處理多個服務請求的事件驅動程序。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/443721.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/443721.shtml
英文地址,請注明出處:http://en.pswp.cn/news/443721.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux服務器 | 服務器模型與三個模塊、兩種并發模式:半同步/半異步、領導者/追隨者

文章目錄兩種服務器模型及三個模塊C/S模型P2P模型I/O處理單元、邏輯單元、存儲單元并發同步與異步半同步/半異步模式變體:半同步/半反應堆模式改進:高效的半同步/半異步模式領導者/追隨者模式組件 :句柄集、線程集、事件處理器工作流程兩種服…

香農信息熵之可憐的小豬

文章目錄題目解析香農熵公式樣例具體分析代碼題目 有 n 桶液體,其其中 正好 有一桶含有毒藥,其裝的都是水。它們從外觀看起來都一樣。為了弄清楚哪只水桶含有毒藥,你可以喂一些豬喝,通過觀察豬是否會死進行判斷,實驗對…

字符串匹配之KMP(KnuthMorrisPratt)算法(圖解)

文章目錄最長相等前后綴next數組概念代碼實現圖解GetNext中的回溯改進代碼實現代碼復雜度分析最長相等前后綴 給出一個字符串 ababa 前綴集合:{a, ab, aba, abab} 后綴集合:{a, ba, aba, baba} 相等前后綴 即上面用同樣顏色標識出來的集合元素&#…

linux下tomcat6.0與jdk安裝詳細步驟

安裝Tomcat6.0和JDK1.6 在linux系統上安裝tomcat和jdk應該說是我學習linux知識的第一課了,之前只 是聽說過,從沒接觸過,但我們公司項目都是部署在linux系統上的,那天上司突 然給我發了幾個文檔,讓我看一下&#xff…

Android入門(一) | Android Studio的配置與使用

文章目錄安裝配置Android Studio使用Android Studio模擬器更改Android SDK的路徑Hello World!安裝配置Android Studio 從這一步開始: 一直點 next 即可,直到存儲路徑的選擇上,可以放到非 C 盤,這里我放到 D 盤了&am…

Android 入門(四) | Intent 實現 Activity 切換

文章目錄Intent顯式 Intent定義兩個 xml 文件android:orientationmatch_parent 和 wrap_contentIntent函數定義兩個 Activity隱式 Intent更多隱式 Intent 的用法用隱式 Intent 打開系統瀏覽器自建 Activity 以響應打開網頁的 Intent向下一個活動傳遞數據返回數據給上一個活動In…

Android入門(二) | 項目目錄及主要文件作用分析

文章目錄項目目錄分析app目錄分析AndroidManifest.xml 分析MainActivity.kt 分析build.gradle 分析最外層目錄下的 build.gradleapp 目錄下的 build.gradle項目目錄分析 我們來看一下 src/main/res 下的一些文件: .gradle 和 .idea :這兩個目錄下放置…

Android入門(三) | Android 的日志工具 Logcat

文章目錄日志工具類 android.util.LogLogcat 中的過濾器日志工具類 android.util.Log Log 從屬日志工具類 android.util.Log ,該類提供了五個方法供我們打印日志: Log.v() :用于打印那些最為瑣碎的、意義最小的日志信息。對應級別 verbose&…

Android 客戶端與服務器交互方式

突然想到一個問題就是Android客戶端與服務器交互有幾種方式,因為在腦袋里想當然的就是webservices和json。要在Android手機客戶端與pc服務器交互,需要滿足下面幾種條件:跨平臺、傳輸數據格式標準、交互方便...。 為了與服務器通訊其實無非就…

Android入門(五) | Activity 的生命周期

文章目錄Activity 的狀態及生命周期實現管理生命周期FirstActivitySecondActivityDialogActivity運行結果舊活動被回收了還能返回嗎?Activity 的狀態及生命周期 Android 的應用程序運用 棧(Back Stack) 的思想來管理 Activity: …

Android入門(六) | Activity 的啟動模式 及 生產環境中關于 Activity 的小技巧

文章目錄Activity 的啟動模式standardsingleTopsingleTasksingleInstance技巧了解當前界面是哪個 Activity隨時隨地退出程序啟動活動的最佳寫法Activity 的啟動模式 standard:默認的啟動方式,每次啟動一個活動都會重新創建singleTop:如果該活…

Android入門(七) | 常用控件

文章目錄TextView 控件:文本信息Button 控件:按鈕EditText 控件:輸入框ImageView 控件:圖片ProgressBar 控件:進度條AlertDialog 控件:提示框ProgressDialog 控件:帶有進度條的提示框TextView 控…

Android入門(八) | 常用的界面布局 及 自定義控件

文章目錄LinearLayout :線性布局android:layout_gravity :控件的對齊方式android:layout_weight:權重RelativeLayout :相對布局相對于父布局進行定位相對于控件進行定位邊緣對齊FrameLayout :幀布局Percent &#xff1…

Android入門(九)| 滾動控件 ListView 與 RecyclerView

文章目錄ListView內置類型的簡單運用定制數據類型提升效率點擊事件RecyclerView布局管理器點擊事件ListView 內置類型的簡單運用 由于手機屏幕空間有限,能夠一次性在屏幕上顯示的內容不多,當我們的程序有大量數據需要顯示的時候就可以借助 ListView 來…

關于“三門問題”的一些想法

三門問題(Monty Hall problem)亦稱為蒙提霍爾問題、蒙特霍問題或蒙提霍爾悖論,大致出自美國的電視游戲節目Let’s Make a Deal。問題名字來自該節目的主持人蒙提霍爾(Monty Hall)。參賽者會看見三扇關閉了的門&#xf…

Android入門(10)| Fragment碎片詳解

文章目錄為什么要使用碎片(Fragment)實例布局文件FragmentActivity動態添加碎片布局文件FragmentActivity碎片通信Fragment布局文件Activity生命周期為什么要使用碎片(Fragment) 我們在手機上看新聞可能是這樣的: Re…

Android開發(1) | Fragment 的應用——新聞應用

文章目錄Item&#xff1a;標題子項布局文件Java代碼標題碎片布局文件Java代碼新聞內容碎片布局文件Java代碼新聞內容活動布局文件Java代碼首界面布局文件Java代碼Item&#xff1a;標題子項 布局文件 news_item.xml&#xff1a; <TextViewxmlns:android"http://schema…

Java Web整體異常處理

在實際的J2EE項目中&#xff0c;系統內部難免會出現一些異常&#xff0c;就如StrutsSpringHibernate項目&#xff1a;通常一個頁面請求到達后臺以后&#xff0c;首先是到action&#xff08;就是MVC中的controller&#xff09;&#xff0c;在action層會調用業務邏輯層service&am…

Android入門(11)| 全局廣播與本地廣播

文章目錄廣播概念接收廣播動態注冊實例靜態注冊實例發送廣播發送標準廣播廣播的跨進程特性發送有序廣播本地廣播廣播概念 Android 中的每個應用程序都可以對自己感興趣的廣播進行注冊&#xff0c;這樣該程序就只會接收到自己所關心的廣播內容&#xff0c;這些廣播可能是來自系…

Android開發(2) | 廣播 Broadcast 的應用——強制下線功能

文章目錄功能簡介關閉所有活動登陸界面發送強制下線的廣播廣播接收器AndroidManifest.xml運行結果功能簡介 強制下線功能只需要彈出一個對話框&#xff0c;讓用戶只能點擊確定按鈕&#xff0c;回到登錄界面。 如果在每一個活動中添加一個對話框的話太過繁瑣&#xff0c;用廣播…