ACE反應(yīng)器(Reactor)模式的深入分析
反應(yīng)器(Reactor):用于事件多路分離和分派的體系結(jié)構(gòu)模式
通常的,對(duì)一個(gè)文件描述符指定的文件或設(shè)備, 有兩種工作方式: 阻塞與非阻塞。所謂阻塞方式的意思是指, 當(dāng)試圖對(duì)該文件描述符進(jìn)行讀寫時(shí), 如果當(dāng)時(shí)沒(méi)有東西可讀,或者暫時(shí)不可寫, 程序就進(jìn)入等待狀態(tài), 直到有東西可讀或者可寫為止。而對(duì)于非阻塞狀態(tài), 如果沒(méi)有東西可讀, 或者不可寫, 讀寫函數(shù)馬上返回, 而不會(huì)等待。
在前面的章節(jié)中提到的Tcp通信的例子中,就是采用的阻塞式的工作方式:當(dāng)接收tcp數(shù)據(jù)時(shí),如果遠(yuǎn)端沒(méi)有數(shù)據(jù)可以讀,則會(huì)一直阻塞到讀到需要的數(shù)據(jù)為止。這種方式的傳輸和傳統(tǒng)的被動(dòng)方法的調(diào)用類似,非常直觀,并且簡(jiǎn)單有效,但是同樣也存在一個(gè)效率問(wèn)題,如果你是開發(fā)一個(gè)面對(duì)著數(shù)千個(gè)連接的服務(wù)器程序,對(duì)每一個(gè)客戶端都采用阻塞的方式通信,如果存在某個(gè)非常耗時(shí)的讀寫操作時(shí),其它的客戶端通信將無(wú)法響應(yīng),效率非常低下。
一種常用做法是:每建立一個(gè)Socket連接時(shí),同時(shí)創(chuàng)建一個(gè)新線程對(duì)該Socket進(jìn)行單獨(dú)通信(采用阻塞的方式通信)。這種方式具有很高的響應(yīng)速度,并且控制起來(lái)也很簡(jiǎn)單,在連接數(shù)較少的時(shí)候非常有效,但是如果對(duì)每一個(gè)連接都產(chǎn)生一個(gè)線程的無(wú)疑是對(duì)系統(tǒng)資源的一種浪費(fèi),如果連接數(shù)較多將會(huì)出現(xiàn)資源不足的情況。
另一種較高效的做法是:服務(wù)器端保存一個(gè)Socket連接列表,然后對(duì)這個(gè)列表進(jìn)行輪詢,如果發(fā)現(xiàn)某個(gè)Socket端口上有數(shù)據(jù)可讀時(shí)(讀就緒),則調(diào)用該socket連接的相應(yīng)讀操作;如果發(fā)現(xiàn)某個(gè)Socket端口上有數(shù)據(jù)可寫時(shí)(寫就緒),則調(diào)用該socket連接的相應(yīng)寫操作;如果某個(gè)端口的Socket連接已經(jīng)中斷,則調(diào)用相應(yīng)的析構(gòu)方法關(guān)閉該端口。這樣能充分利用服務(wù)器資源,效率得到了很大提高。
在Socket編程中就可以通過(guò)select等相關(guān)API實(shí)現(xiàn)這一方式。但直接用這些API控制起來(lái)比較麻煩,并且也難以控制和移植,在ACE中可以通過(guò)Reactor模式簡(jiǎn)化這一開發(fā)過(guò)程。
反應(yīng)器本質(zhì)上提供一組更高級(jí)的編程抽象,簡(jiǎn)化了事件驅(qū)動(dòng)的分布式應(yīng)用的設(shè)計(jì)和實(shí)現(xiàn)。除此而外,反應(yīng)器還將若干不同種類的事件的多路分離集成到易于使用的API中。特別地,反應(yīng)器對(duì)基于定時(shí)器的事件、信號(hào)事件、基于I/O端口監(jiān)控的事件和用戶定義的通知進(jìn)行統(tǒng)一地處理。
ACE中的反應(yīng)器與若干內(nèi)部和外部組件協(xié)同工作。其基本概念是反應(yīng)器框架檢測(cè)事件的發(fā)生(通過(guò)在OS事件多路分離接口上進(jìn)行偵聽),并發(fā)出對(duì)預(yù)登記事件處理器(event handler)對(duì)象中的方法的"回調(diào)"(callback)。該方法由應(yīng)用開發(fā)者實(shí)現(xiàn),其中含有應(yīng)用處理此事件的特定代碼。
使用ACE的反應(yīng)器,只需如下幾步:
創(chuàng)建事件處理器,以處理他所感興趣的某事件。
在反應(yīng)器上登記,通知說(shuō)他有興趣處理某事件,同時(shí)傳遞他想要用以處理此事件的事件處理器的指針給反應(yīng)器。
隨后反應(yīng)器框架將自動(dòng)地:
在內(nèi)部維護(hù)一些表,將不同的事件類型與事件處理器對(duì)象關(guān)聯(lián)起來(lái)。
在用戶已登記的某個(gè)事件發(fā)生時(shí),反應(yīng)器發(fā)出對(duì)處理器中相應(yīng)方法的回調(diào)。
反應(yīng)器模式在ACE中被實(shí)現(xiàn)為ACE_Reactor類,它提供反應(yīng)器框架的功能接口。
如上面所提到的,反應(yīng)器將事件處理器對(duì)象作為服務(wù)提供者使用。反應(yīng)器內(nèi)部記錄某個(gè)事件處理器的特定事件的相關(guān)回調(diào)方法。當(dāng)這些事件發(fā)生時(shí),反應(yīng)器會(huì)創(chuàng)建這種事件和相應(yīng)的事件處理器的關(guān)聯(lián)。
事件處理器
事件處理器就是需要通過(guò)輪詢發(fā)生事件改變的對(duì)象列表中的對(duì)象,如在上面的例子中就是連接的客戶端,每個(gè)客戶端都可以看成一個(gè)事件處理器。
回調(diào)事件
就是反應(yīng)器支持的事件,如Socket讀就緒,寫就緒。拿上面的例子來(lái)說(shuō),如果某個(gè)客戶端(事件處理器)在反應(yīng)器中注冊(cè)了讀就緒事件,當(dāng)客戶端給服務(wù)器發(fā)送一條消息的時(shí)候,就會(huì)觸發(fā)這個(gè)客戶端的數(shù)據(jù)可讀的回調(diào)函數(shù)。
在反應(yīng)器框架中,所有應(yīng)用特有的事件處理器都必須由ACE_Event_Handler的抽象接口類派生??梢酝ㄟ^(guò)重載相應(yīng)的"handle_"方法實(shí)現(xiàn)相關(guān)的回調(diào)方法。
使用ACE_Reactor基本上有三個(gè)步驟:
創(chuàng)建ACE_Event_Handler的子類,并在其中實(shí)現(xiàn)適當(dāng)?shù)?handle_"方法,以處理你想要此事件處理器為之服務(wù)的事件類型。
通過(guò)調(diào)用反應(yīng)器對(duì)象的register_handler(),將你的事件處理器登記到反應(yīng)器。
在事件發(fā)生時(shí),反應(yīng)器將自動(dòng)回調(diào)相應(yīng)的事件處理器對(duì)象的適當(dāng)?shù)膆andle_"方法。
- Java Reactor反應(yīng)器模式使用方法詳解
- 簡(jiǎn)單了解Java Netty Reactor三種線程模型
- 詳解Python的Twisted框架中reactor事件管理器的用法
- Reactor反應(yīng)器的實(shí)現(xiàn)方法詳解
- IDEA上運(yùn)行Flink任務(wù)的實(shí)戰(zhàn)教程
- Flink開發(fā)IDEA環(huán)境搭建與測(cè)試的方法
- Java lambda表達(dá)式實(shí)現(xiàn)Flink WordCount過(guò)程解析
- Apache Flink 任意 Jar 包上傳導(dǎo)致遠(yuǎn)程代碼執(zhí)行漏洞復(fù)現(xiàn)問(wèn)題(漏洞預(yù)警)
- Apache FlinkCEP 實(shí)現(xiàn)超時(shí)狀態(tài)監(jiān)控的步驟詳解
- 大數(shù)據(jù)HelloWorld-Flink實(shí)現(xiàn)WordCount
- 如何使用Reactor完成類似Flink的操作
相關(guān)文章
C++解決TCP粘包的問(wèn)題實(shí)現(xiàn)
本文主要介紹了C++解決TCP粘包的問(wèn)題實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08函數(shù)指針與指針函數(shù)的學(xué)習(xí)總結(jié)
函數(shù)指針是指向函數(shù)的指針,指針函數(shù)是指一個(gè)函數(shù)的返回值是一個(gè)指針。以下就是對(duì)函數(shù)指針與指針函數(shù)的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下2013-07-07C++的std::transform()的實(shí)現(xiàn)
在 C++ 標(biāo)準(zhǔn)庫(kù)中,std::transform() 是一個(gè)非常有用的算法函數(shù),它能夠?qū)⒔o定范圍中的每個(gè)元素進(jìn)行變換,并將變換后的結(jié)果存儲(chǔ)到另一個(gè)范圍中,本文就詳細(xì)的介紹一下具體用法,感興趣的可以了解一下2023-08-08c++ chrono 獲取當(dāng)前時(shí)間的實(shí)現(xiàn)代碼
這篇文章主要介紹了c++ chrono 獲取當(dāng)前時(shí)間的實(shí)現(xiàn)代碼,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07C++實(shí)現(xiàn)帶頭雙向循環(huán)鏈表的示例詳解
這篇文章主要介紹了如何利用C++實(shí)現(xiàn)帶頭雙向循環(huán)鏈表,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-12-12C++實(shí)現(xiàn)十大排序算法及排序算法常見(jiàn)問(wèn)題
法是程序的靈魂,無(wú)論學(xué)習(xí)什么語(yǔ)言,做什么工程項(xiàng)目,都要考慮算法的效率實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于C++實(shí)現(xiàn)十大排序算法及排序算法常見(jiàn)問(wèn)題的相關(guān)資料,需要的朋友可以參考下2021-09-09