Reactor和Proactor模式

在高性能的I/O設計中,有兩個比較著名的模式Reactor和Proactor模式,其中Reactor模式用於同步I/O,而Proactor運用於異步I/O操做。 
同步和異步 
同步和異步是針對應用程序和內核的交互而言的,同步指的是用戶進程觸發IO操做並等待或者輪詢的去查看IO操做是否就緒,而異步是指用戶進程觸發IO操做之後便開始作本身的事情,而當IO操做已經完成的時候會獲得IO完成的通知。 
阻塞和非阻塞 
阻塞方式下讀取或者寫入函數將一直等待,而非阻塞方式下,讀取或者寫入函數會當即返回一個狀態值。 

I/O模型能夠分爲:同步阻塞,同步非阻塞,異步阻塞,異步非阻塞IO 
1.同步阻塞 
用戶進程在發起一個IO操做之後,必須等待IO操做的完成,只有當真正完成了IO操做之後,用戶進程才能運行。JAVA傳統的IO模型屬於此種方式! 

2.同步非阻塞 
用戶進程發起一個IO操做之後邊可返回作其它事情,可是用戶進程須要時不時的詢問IO操做是否就緒,這就要求用戶進程不停的去詢問,從而引入沒必要要的CPU資源浪費。其中目前JAVA的NIO就屬於同步非阻塞IO。 

3.異步阻塞 
此種方式下是指應用發起一個IO操做之後,不等待內核IO操做的完成,等內核完成IO操做之後會通知應用程序,這其實就是同步和異步最關鍵的區別,同步必須等待或者主動的去詢問IO是否完成,那麼爲何說是阻塞的呢?由於此時是經過select系統調用來完成的,而select函數自己的實現方式是阻塞的,而採用select函數有個好處就是它能夠同時監聽多個文件句柄,從而提升系統的併發性! 

4.異步非阻塞 
用戶進程只須要發起一個IO操做而後當即返回,等IO操做真正的完成之後,應用程序會獲得IO操做完成的通知,此時用戶進程只須要對數據進行處理就行了,不須要進行實際的IO讀寫操做,由於真正的IO讀取或者寫入操做已經由內核完成了。目前Java中尚未支持此種IO模型。 

綜上所述,同步和異步是相對於應用和內核的交互方式而言的,同步 須要主動去詢問,而異步的時候內核在IO事件發生的時候通知應用程序,而阻塞和非阻塞僅僅是系統在調用系統調用的時候函數的實現方式而已。 

Reactor模式 
不少地方叫反應器模式,併發系統常使用reactor模式,代替經常使用的多線程的處理方式,節省系統的資源,提升系統的吞吐量。 
例如:在高併發的狀況下 
多線程的處理:爲每一個單獨到來的請求,專門啓動一條線程,這樣的話形成系統的開銷很大,而且在單核的機上,多線程並不能提升系統的性能,除非在有一些阻塞的狀況發生。不然線程切換的開銷會使處理的速度變慢。 
Reactor模式的處理:服務器端啓動一條單線程,用於輪詢IO操做是否就緒,當有就緒的才進行相應的讀寫操做,這樣的話就減小了服務器產生大量的線程,也不會出現線程之間的切換產生的性能消耗。(目前JAVA的NIO就採用的此種模式,這裏引伸出一個問題:在多核狀況下NIO的擴展問題) 

以上兩種處理方式都是基於同步的,多線程的處理是咱們傳統模式下對高併發的處理方式,Reactor模式的處理是現今面對高併發和高性能一種主流的處理方式。 

Proactor模式  運用於異步I/O操做,Proactor模式中,應用程序不須要進行實際的讀寫過程,它只須要從緩存區讀取或者寫入便可,操做系統會讀取緩存區或者寫入緩存區到真正的IO設備. 
相關文章
相關標籤/搜索