Reactor

Reactor框架是ACE各個(gè)框架中最基礎(chǔ)的一個(gè)框架,其他框架都或多或少地用到了Reactor框架。本文分析Reactor構(gòu)架模式的基本原理。

2.1? Reactor構(gòu)架模式

對(duì)每一個(gè)構(gòu)架模式的分析,我們都使用參考文獻(xiàn)的分析風(fēng)格,著重分析意圖、上下文、問(wèn)題、解決方案、結(jié)構(gòu)和實(shí)現(xiàn) 6個(gè)方面的內(nèi)容。而實(shí)現(xiàn)就是ACE源代碼。

1. 意圖

在事件驅(qū)動(dòng)的應(yīng)用中,將一個(gè)或多個(gè)客戶的服務(wù)請(qǐng)求分離(demultiplex)和調(diào)度(dispatch)給應(yīng)用程序。

2. 上下文

在事件驅(qū)動(dòng)的應(yīng)用中,同步地、有序地處理同時(shí)接收的多個(gè)服務(wù)請(qǐng)求。

3. 問(wèn)題

在分布式系統(tǒng)尤其是服務(wù)器這一類事件驅(qū)動(dòng)應(yīng)用中,雖然這些請(qǐng)求最終會(huì)被序列化地處理,但是必須時(shí)刻準(zhǔn)備著處理多個(gè)同時(shí)到來(lái)的服務(wù)請(qǐng)求。在實(shí)際應(yīng)用 中,這些請(qǐng)求總是通過(guò)一個(gè)事件(如CONNECTOR、READ、WRITE等)來(lái)表示的。在有序地處理這些服務(wù)請(qǐng)求之前,應(yīng)用程序必須先分離和調(diào)度這些 同時(shí)到達(dá)的事件。為了有效地解決這個(gè)問(wèn)題,我們需要做到以下4方面:

為了提高系統(tǒng)的可測(cè)量性和反應(yīng)時(shí)間,應(yīng)用程序不能長(zhǎng)時(shí)間阻塞在某個(gè)事件源上而停止對(duì)其他事件的處理,這樣會(huì)嚴(yán)重降低對(duì)客戶端的響應(yīng)度。

為了提高吞吐量,任何沒(méi)有必要的上下文切換、同步和CPU之間的數(shù)據(jù)移動(dòng)都要避免。

引進(jìn)新的服務(wù)或改良已有的服務(wù)都要對(duì)既有的事件分離和調(diào)度機(jī)制帶來(lái)盡可能小的影響。

大量的應(yīng)用程序代碼需要隱藏在復(fù)雜的多線程和同步機(jī)制之后。

4. 解決方案

在一個(gè)或多個(gè)事件源上等待事件的到來(lái),例如,一個(gè)已經(jīng)連接的Socket描述符就是一個(gè)事件源。將事件的分離和調(diào)度整合到處理它的服務(wù)中,而將分離和調(diào)度機(jī)制從應(yīng)用程序?qū)μ囟ㄊ录奶幚碇蟹蛛x開(kāi),也就是說(shuō)分離和調(diào)度機(jī)制與特定的應(yīng)用程序無(wú)關(guān)。

具體來(lái)說(shuō),每個(gè)應(yīng)用程序提供的每個(gè)服務(wù)都有一個(gè)獨(dú)立的事件處理器與之對(duì)應(yīng)。由事件處理器處理來(lái)自事件源的特定類型的事件。每個(gè)事件處理器都事先注冊(cè) 到Reactor管理器中。Reactor管理器使用同步事件分離器在一個(gè)或多個(gè)事件源中等待事件的發(fā)生。當(dāng)事件發(fā)生后,同步事件分離器通知 Reactor管理器,最后由Reactor管理器調(diào)度和該事件相關(guān)的事件處理器來(lái)完成請(qǐng)求的服務(wù)。

5. 結(jié)構(gòu)

在Reactor模式中,有5個(gè)關(guān)鍵的參與者。

描述符(handle):由操作系統(tǒng)提供,用于識(shí)別每一個(gè)事件,如Socket描述符、文件描述符等。在Linux中,它用一個(gè)整數(shù)來(lái)表示。事件可以來(lái)自外部,如來(lái)自客戶端的連接請(qǐng)求、數(shù)據(jù)等。事件也可以來(lái)自內(nèi)部,如定時(shí)器事件。

同步事件分離器(demultiplexer):是一個(gè)函數(shù),用來(lái)等待一個(gè)或多個(gè)事件的發(fā)生。調(diào)用者會(huì)被阻塞,直到分離器分離的描述符集上有事件發(fā)生。Linux的select函數(shù)是一個(gè)經(jīng)常被使用的分離器。

事件處理器接口(event handler):是由一個(gè)或多個(gè)模板函數(shù)組成的接口。這些模板函數(shù)描述了和應(yīng)用程序相關(guān)的對(duì)某個(gè)事件的操作。

具體的事件處理器:是事件處理器接口的實(shí)現(xiàn)。它實(shí)現(xiàn)了應(yīng)用程序提供的某個(gè)服務(wù)。每個(gè)具體的事件處理器總和一個(gè)描述符相關(guān)。它使用描述符來(lái)識(shí)別事件、識(shí)別應(yīng)用程序提供的服務(wù)。

Reactor 管理器(reactor):定義了一些接口,用于應(yīng)用程序控制事件調(diào)度,以及應(yīng)用程序注冊(cè)、刪除事件處理器和相關(guān)的描述符。它是事件處理器的調(diào)度核心。 Reactor管理器使用同步事件分離器來(lái)等待事件的發(fā)生。一旦事件發(fā)生,Reactor管理器先是分離每個(gè)事件,然后調(diào)度事件處理器,最后調(diào)用相關(guān)的模 板函數(shù)來(lái)處理這個(gè)事件。

通過(guò)上述分析,我們注意到,是Reactor管理器而不是應(yīng)用程序負(fù)責(zé)等待事件、分離事件和調(diào)度事件。實(shí)際上,Reactor管理器并沒(méi)有被具體的 事件處理器調(diào)用,而是管理器調(diào)度具體的事件處理器,由事件處理器對(duì)發(fā)生的事件做出處理。這就是類似Hollywood原則的“反向控制”。應(yīng)用程序要做的 僅僅是實(shí)現(xiàn)一個(gè)具體的事件處理器,然后把它注冊(cè)到Reactor管理器中。接下來(lái)的工作由管理器來(lái)完成。這些參與者的相互關(guān)系如圖2-1所示。

現(xiàn)在結(jié)合第1章分析的框架五元素來(lái)看一下Reactor構(gòu)架模式的參與者與框架五元素之間的關(guān)系:Reactor構(gòu)架模式的具體實(shí)現(xiàn)對(duì)應(yīng)了元素1; 事件處理器接口對(duì)應(yīng)元素2;具體的事件處理器對(duì)應(yīng)元素3;Reactor管理器使用了Hollywood原則,可以認(rèn)為和元素5對(duì)應(yīng);元素4的功能相對(duì)不 明顯,沒(méi)有明確的對(duì)應(yīng)關(guān)系。

如果還是沒(méi)有理解Reactor構(gòu)架模式,沒(méi)有關(guān)系,源代碼會(huì)說(shuō)明所有問(wèn)題。此時(shí)可再分析一遍Reactor構(gòu)架模式,然后繼續(xù)以下內(nèi)容。

file:///C:/Users/Administrator/AppData/Local/YNote/data/xzyeah@yeah.net/22cd79896cce4cdf86414e34f3e89c5d/1342687408_4917.jpg.jpeg

圖2-1? Reactor構(gòu)架模式結(jié)構(gòu)圖

2.2? Reactor框架概述

從對(duì)Reactor構(gòu)架模式的分析中我們可以看出,要設(shè)計(jì)和實(shí)現(xiàn)一個(gè)簡(jiǎn)單Reactor框架以支持I/O事件,需要實(shí)現(xiàn)兩個(gè)組件:事件處理器接口和 Reactor管理器。至于其他組件,如同步事件分離器可以使用操作系統(tǒng)提供的select、poll或其他類似的函數(shù);而描述符可以使用文件描述符或其 他可以識(shí)別事件的數(shù)據(jù)結(jié)構(gòu),一般操作系統(tǒng)都會(huì)提供。事件處理器接口包含一系列模板函數(shù),可以根據(jù)實(shí)際處理的數(shù)據(jù)進(jìn)行設(shè)計(jì);Reactor管理器肩負(fù)著事件 的分離和調(diào)度,是整個(gè)框架設(shè)計(jì)的核心。

ACE的Reactor框架在Linux平臺(tái)下使用文件描述符作為I/O事件的描述符,使用ACE_Event_Handler類作為各類事件的處 理器接口。將同步事件分離函數(shù)放到Reactor管理器中,這樣使用不同的同步事件分離函數(shù)就需要實(shí)現(xiàn)不同的Reactor管理器。ACE使用 Bridge設(shè)計(jì)模式解決了這一問(wèn)題,將與同步事件分離函數(shù)相關(guān)的操作放到Bridge設(shè)計(jì)模式的Implementor中。凡是ACE支持的同步事件分 離函數(shù)都會(huì)有一個(gè)具體的Implementor與之對(duì)應(yīng)。

ACE的Reactor管理器還提供了用于實(shí)現(xiàn)Singleton設(shè)計(jì)模式的操作,使用這些操作時(shí),一個(gè)進(jìn)程只能有一個(gè)全局的Reactor管理 器。在調(diào)用Singleton設(shè)計(jì)模式接口時(shí),Reactor管理器會(huì)在啟動(dòng)時(shí)根據(jù)操作系統(tǒng)的配置選擇一個(gè)具體的Implementor。當(dāng)然,如果你不 喜歡這個(gè)默認(rèn)的Implementor,可以通過(guò)函數(shù)進(jìn)行更換。為了提高整個(gè)系統(tǒng)對(duì)事件分離和調(diào)度的性能,ACE還允許應(yīng)用程序創(chuàng)建多個(gè)Reactor管 理器實(shí)例。在這種情況下,應(yīng)用程序?qū)⒉荒苷{(diào)用用于Singleton設(shè)計(jì)模式的操作,只能直接使用Reactor管理器實(shí)例對(duì)象的方法實(shí)現(xiàn)對(duì)事件的分離和 調(diào)度。同時(shí)提供這兩種使用方法,可以最大程度地滿足應(yīng)用程序的苛刻要求。

ACE實(shí)現(xiàn)的Reactor框架結(jié)構(gòu)要比Reactor構(gòu)架模式中分析的結(jié)構(gòu)復(fù)雜得多。這是因?yàn)锳CE的Reactor框架除了處理I/O事件之 外,還要處理定時(shí)器、信號(hào)量等常見(jiàn)的事件,并且所有的這些處理都必須滿足跨平臺(tái)的要求。要將對(duì)這些事件的處理抽象出來(lái),并且提供給應(yīng)用程序一個(gè)統(tǒng)一的接 口,ACE的Reactor管理器的實(shí)現(xiàn)還采用了Facade設(shè)計(jì)模式。實(shí)際上,Reactor框架管理的I/O事件、信號(hào)量事件、定時(shí)器事件和 Notify事件在實(shí)現(xiàn)上都有一個(gè)小的組件與之對(duì)應(yīng),這樣可以將Reactor管理器與具體的事件處理解耦。使用Facade設(shè)計(jì)模式,將這些小的組件的 接口封裝起來(lái),使得應(yīng)用程序無(wú)法感知它們的存在,可以減少應(yīng)用程序處理對(duì)象的數(shù)目,并且使得這些小的組件使用起來(lái)更加方便。

以上分析的3種設(shè)計(jì)模式以及Factory設(shè)計(jì)模式,在ACE的框架管理器的實(shí)現(xiàn)中被頻繁使用。這些設(shè)計(jì)模式以及它們的使用,既為我們學(xué)習(xí)設(shè)計(jì)模式 提供了非常好的場(chǎng)景,又為我們實(shí)現(xiàn)軟件框架管理器提供了實(shí)用的方法。ACE的Reactor框架與框架五元素的對(duì)應(yīng)關(guān)系非常密切,是一個(gè)典型的事件驅(qū)動(dòng)型 框架,它為我們打開(kāi)了ACE的框架之門,是學(xué)習(xí)其他框架的基礎(chǔ)。

在深入到框架代碼之前,我們先來(lái)看一個(gè)Reactor框架的使用示例,示例雖然簡(jiǎn)單,但卻提供了一個(gè)實(shí)實(shí)在在的應(yīng)用程序,也為我們的分析提供了一些思路。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容