ACE中的Proactor和Reactor
生活随笔
收集整理的這篇文章主要介紹了
ACE中的Proactor和Reactor
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
ACE中的Proactor和Reactor
? ? ? ? ACE_Select_Reactor是除Windows之外所有平臺使用的默認反應器實現,在這些系統上最終會用select()系統函數進行等待。在Windows上ACE_WFMO_Reactor是默認的反應器實現。該實現沒有使用select()多路分離器,而是使用了WaitForMultipleObjects()。在使用ACE_WFMO_Reactor時,需要一些權衡:ACE_WFMO_Reactor只能登記62個句柄。底層的WaitForMutipleObejcts()函數是64個,ACE在內部使用了其中的兩個;I/O類型,ACE_WFMO_Reactor只在socket句柄上支持handler_input()、handler_output()和handler_exception()的I/O回調;只要句柄能用于WaitForMultipleObjects(),ACE_WFMO_Reactor就能對其做出反應,比如文件變更通知句柄和事件句柄。
? ? ? ?ACE_WIN32_Proactor是Windows上的ACE_Proactor實現,它使用I/O完成多口進行完成事件檢測。在初始化異步操作工廠時(比如ACE_Asynch_Read_Stream或ACE_Aysnch_Write_Stream),I/O句柄會與Proactor的I/O完成端口關聯在一起。在這種實現里,Windows的GetQueuedCompletionStatus()函數用于執行時間循環。多個線程可以同時執行ACE_WIN32_Proactor時間循環。POSIX系統上的ACE?Proactor實現提供了多種用于發起I/O操作、并檢查其完成的機制。ACE所封裝的POSIX異步I/O機制支持read()和write()操作,但不支持與TCP/IP連接相關的操作,為了支持ACE_Asynch_Acceptro和ACE_Asynch_Connector的函數,ACE使用了一個單獨的線程來執行與連接有關的操作。因此,在POSIX平臺上使用Proactor框架時,程序將會運行多個線程。ACE的內部機制使得你不用再多個線程中對時間進行處理,所以你無需增加任何特殊的加鎖或同步。
? ? ? ? 首先想寫網絡處理程序,那么要清楚各個步驟的限制是什么,簡單的說,肯定有讀取(寫)數據,和處理數據兩個部分,那么這個兩個部分有什么特點呢?讀取數據主要是I/O操作,而單個的I/O操作可能會有等待,而且I/O操作對CPU的耗費很少,最重要的是I/O速度與CPU速度比跟龜速差不多。一個線程就可以處理很多路的I/O操作,在一次I/O完成的時候會激活分離器,由分離器調用事件處理器。做個假設,可能同時有1000個數據請求,如果不用reactor,那么可能會開啟1000個線程或者進程進行服務,這個時候首先線程之間的切換和鎖開銷是非常大的,而如果采用reactor,可能會只用一個讀線程,輪流讀取這1000個請求,然后當其中的一個讀取完成后,激活分離器,分離器調用事件處理器,這樣的話,如果系統處理數據很快的話,那么同時存在的線程可能很少,就減少了系統的線程創建切換和銷毀。
? ? ? ? 記得以前寫過的服務器程序,都是有一個讀取請求線程池,一個處理線程池,這樣的話其實和Reactor模式的原理差不多,把讀取和處理分離開來,然后用一個消息隊列來完成讀取與處理的通信,這樣會用到鎖,鎖的設計不僅復雜而且會有系統開銷。但是Reactor沒有用鎖,只把一個buffer告訴分發器,當讀取結束就回調處理handler。(在ACE中是否用鎖實現的不是很確定)而且,想剛才那樣設計交互就比較麻煩,如果光是讀還比較簡單,但是讀到如果會送那么就比較麻煩了。
下面是別的博文上總結Reactor和Proactor的讀的過程:
在Reactor中實現讀:- 注冊讀就緒事件和相應的事件處理器
- 事件分離器等待事件
- 事件到來,激活分離器,分離器調用事件對應的處理器。
- 事件處理器完成實際的讀操作,處理讀到的數據,注冊新的事件,然后返還控制權。
在Proactor中實現讀:- 處理器發起異步讀操作(注意:操作系統必須支持異步IO)。在這種情況下,處理器無視IO就緒事件,它關注的是完成事件。
- 事件分離器等待操作完成事件
- 在分離器等待過程中,操作系統利用并行的內核線程執行實際的讀操作,并將結果數據存入用戶自定義緩沖區,最后通知事件分離器讀操作完成。
- 事件分離器呼喚處理器。
- 事件處理器處理用戶自定義緩沖區中的數據,然后啟動一個新的異步操作,并將控制權返回事件分離器
簡單總結下相同點與不同點:
相同點
1)都有Event Demutiplexer(為什么叫事件多路分離器呢?主要是從它的功能上看,它能夠把事件源的I/O時間分離出來,并分發到對應的read/write事件處理區(Event Handler)),負責回調handler。
2)讀(寫)數據,與讀結束后處理為分開的兩個過程,這也是Reactor的重點所在,不用一個線程完成從讀數據一直到處理結束,讀數據線程和處理線程是兩個不同的線程。這樣做有個優點,因為讀取數據可能會很耗費時間,讀取其實瓶頸為系統的I/O,一個線程就可以處理很多路數據的I/O處理。
不同點:
1)Proactor是在I/O操作完成才回調handler,而Reactor是在I/O可以進行讀或寫操作時候調用handler。
2)Proactor的讀寫是利用操作系統支持異步I/O讀寫操作完成的,而Reactor的I/O操作是由用戶完成的。
3)Reactor為同步的,需要用戶自己去執行I/O操作然后等待I/O操作完成,在執行某些操作,Proactor為異步的,發起I/O操作后就交給操作系統了,只關心IO完成事件。這里一開始理解有個小的誤區,
? ? ? ? 其實Reactor和Proactor在等待I/O事件到來的時候都可以理解為異步的,可能都用到select()底層函數,當端口可操作時候由操作系統異步的通知,這個時候Reactor收到通知,調用handler。然而Proactor收到端口可操作的時候還不滿意,需要在I/O操作完成后再異步的通知,這樣Proactor相當于兩層異步操作,而說Reactor和Proactor的“異步”,指的為后面的I/O操作。
? ? ? ? “Reactor框架中用戶定義的操作是在實際操作之前調用的。比如你定義了操作是要向一個SOCKET寫數據,那么當該SOCKET可以接收數據的時候,你的操作就會被調用;而Proactor框架中用戶定義的操作是在實際操作之后調用的。比如你定義了一個操作要顯示從SOCKET中讀入的數據,那么當讀操作完成以后,你的操作才會被調用?!?br />
參考:
http://www.cnblogs.com/dawen/archive/2011/05/18/2050358.htmlhttp://name5566.com/4175.html 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的ACE中的Proactor和Reactor的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ACE_Proactor UDP V2.
- 下一篇: 高性能I/O设计模式Reactor和Pr