ICE系列培訓(xùn)(二)_第1頁(yè)
ICE系列培訓(xùn)(二)_第2頁(yè)
ICE系列培訓(xùn)(二)_第3頁(yè)
ICE系列培訓(xùn)(二)_第4頁(yè)
ICE系列培訓(xùn)(二)_第5頁(yè)
已閱讀5頁(yè),還剩58頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、ICE系列培訓(xùn)(二)黃亮統(tǒng)一網(wǎng)管平臺(tái)專項(xiàng)培訓(xùn)內(nèi)容ICE中的異步程序設(shè)計(jì)方法(AMD,AMI)1.AMI:Asynchronous Method Invocation異步方法調(diào)用2.AMD:Asynchronous Method Dispatch異步方法派發(fā)1. 概述1.1 同步模型與異步模型區(qū)別1.2 AMI概述1.3 AMD概述1.4 元數(shù)據(jù)(metadata)與AMI,AMD1.1 同步模型與異步模型區(qū)別兩者的區(qū)別:同步模型中發(fā)出調(diào)用的線程會(huì)阻塞到操作返回。異步模型則正好相反,發(fā)出調(diào)用的線程不會(huì)阻塞的等待調(diào)用結(jié)果的返回。Ice 在本質(zhì)上是一個(gè)異步的中間件平臺(tái),出于對(duì)應(yīng)用 (及其程序員)的考

2、慮而模擬了同步的行為。當(dāng) Ice 應(yīng)用通過(guò)代理、向遠(yuǎn)地對(duì)象發(fā)出同步的雙向調(diào)用時(shí),發(fā)出調(diào)用的線程會(huì)阻塞起來(lái),以模擬同步的方法調(diào)用。在此期間, Ice run time在后臺(tái)運(yùn)行,處理消息,直到收到所需的答復(fù)為止,然后發(fā)出調(diào)用的線程就可以解除阻塞并解編結(jié)果。1.2 AMI概述AMI:異步方法調(diào)用這個(gè)術(shù)語(yǔ)描述的是客戶端的異步編程模型支持。使用 AMI發(fā)出遠(yuǎn)地調(diào)用,在 Ice run time 等待答復(fù)的同時(shí),發(fā)出調(diào)用的線程不會(huì)阻塞。相反,發(fā)出調(diào)用的線程可以繼續(xù)進(jìn)行各種活動(dòng),當(dāng)答復(fù)最終到達(dá)時(shí), Ice run time會(huì)通知應(yīng)用。通過(guò)回調(diào)發(fā)給應(yīng)用對(duì)象通知1.3 AMD概述AMD:使用 AMD 時(shí),服務(wù)

3、器可以接收一個(gè)請(qǐng)求,然后掛起其處理,以盡快釋放分派線程。當(dāng)處理恢復(fù)、結(jié)果已得出時(shí),服務(wù)器要使用 Ice run time 提供的回調(diào)對(duì)象,顯式地發(fā)送響應(yīng)。AMD 操作通常會(huì)把請(qǐng)求數(shù)據(jù) (也就是,回調(diào)對(duì)象和操作參數(shù))放入隊(duì)列 ,供應(yīng)用的某個(gè)線程 (或線程池)隨后處理用。這樣,服務(wù)器就使分派線程的使用率降到了最低限度,能夠高效地支持?jǐn)?shù)千并發(fā)客戶。1.3 AMD概述為什么要使用AMD:(1)默認(rèn)情況下:一個(gè)服務(wù)器在同一時(shí)刻所能支持的同步請(qǐng)求數(shù)受到 Ice run time的服務(wù)器線程池的尺寸限制 。如果所有線程都在忙于分派長(zhǎng)時(shí)間運(yùn)行的操作,那么就沒(méi)有線程可用于處理新的請(qǐng)求,客戶就會(huì)體驗(yàn)到不可接受的無(wú)

4、響應(yīng)狀態(tài)。(2)Ice run time的服務(wù)器線程池尺寸受限于主機(jī)的CPU數(shù)。1.4 元數(shù)據(jù)與AMI,AMD1)ICE自3.4以后,提供了一套全新的AMI(異步調(diào)用方式)的API,新的API已不需要在slice文件中標(biāo)記“ami”這樣的元數(shù)據(jù)。2)ICE提供向下兼容性,支持“ami”的語(yǔ)言標(biāo)記,但已標(biāo)注為deprecated.3) 服務(wù)端使用AMD異步派發(fā)方式編程,仍然必須在slice文件中,對(duì)slice定義標(biāo)注“amd”元數(shù)據(jù)。Tips:給客戶提供某個(gè)調(diào)用方法的同步和異步版本是有益的,但如果在服務(wù)器中這樣做,程序員就必須實(shí)現(xiàn)兩種版本的分派方法,并不能帶來(lái)切實(shí)的好處,而且還會(huì)帶來(lái)若干潛在的缺

5、陷。1.4 元數(shù)據(jù)與AMI,AMDAMD元數(shù)據(jù)標(biāo)記方式:1)接口級(jí)(interface)amd interface I bool isValid(); float computeRate();2) 操作級(jí)(operation)interface J amd void startProcess(); int endProcess();1.4 元數(shù)據(jù)與AMI,AMDAMD元數(shù)據(jù)的標(biāo)記方式Tips:在操作層面、而不是接口或類的層面指定元數(shù)據(jù),不僅能使所生成的代碼的數(shù)量降到最低限度,而且,更重要的是,它還能使復(fù)雜度降到最低限度。盡管異步模型更為靈活,它的使用也更復(fù)雜。因此,最好只把它用于那些能從中獲得

6、某種好處的操作;對(duì)其他操作則使用更簡(jiǎn)單的同步模型。2. AMI編程2.1 基本API2.2 AsynResult類2.3 輪詢方式的完成通知(Polling for Completion)2.4 通用的完成通知回調(diào)函數(shù)(Generic Completion Callbacks)2.5 類型安全的回調(diào)(Type-Safe Completion Callbacks)2.6 單路調(diào)用(Oneway Invocations)2.7 流量控制(Flow Control)2.8 批量請(qǐng)求(Batch Requests)2.9 并發(fā)(Concurrency)2.10 限制(Limitations)2.11

7、示例 2.1 Slice介紹(1)Slice是什么Slice(Specification Language for Ice)是分離對(duì)象接口和實(shí)現(xiàn)的重要抽象機(jī)制。Slice建立了客戶和服務(wù)器之間的契約,這些契約描述了應(yīng)用所需的類型及對(duì)象接口。這些描述是中立與語(yǔ)言的,所以客戶端和服務(wù)端可以使用不同的實(shí)現(xiàn)語(yǔ)言。Slice提供編譯工具將Slice定義編譯為具體語(yǔ)言的實(shí)現(xiàn)代碼,即客戶端的Proxy code和服務(wù)端的Skeleton,這樣用戶只用把注意力放在業(yè)務(wù)邏輯的處理上。2.1 Basic Asynchronous API1.異步方法通知(AMI)APIICE從3.4開(kāi)始采用新的AMI API:mo

8、dule Demo interface Employees string getName(int number); ;1)不必再顯式的注明“ami”元數(shù)據(jù),slice工具會(huì)自動(dòng)的生產(chǎn)同步調(diào)用與異步調(diào)用的stub代碼。Ice:AsyncResultPtr begin_getName(Ice:Int number);Ice:AsyncResultPtr begin_getName(Ice:Int number, const Ice:Context& _ctx);std:string end_getName(const Ice:AsyncResultPtr&);2.1 Basic Asynchron

9、ous API(2)begin_xxxMethod負(fù)責(zé)向隊(duì)列中插入一個(gè)調(diào)用的請(qǐng)求,當(dāng)請(qǐng)求插入到隊(duì)列后,便可立即返回,不必阻塞的等待調(diào)用完成。(3)end_xxxMethod負(fù)責(zé)收集異步調(diào)用的結(jié)果。當(dāng)異步調(diào)用的結(jié)果還未處理完成時(shí),調(diào)用end_xxxMethod方法會(huì)阻塞到異步調(diào)用完成處理結(jié)果。換句話說(shuō),如果結(jié)果已完成,調(diào)用end_xxxMethod方法會(huì)立即返回。示例:EmployeesPrx e = .;Ice:AsyncResultPtr r = e-begin_getName(99);/ Continue to do other things here.string name = e-en

10、d_getName(r);Tips:AsyncResultPtr是AsynResult的智能指針,存儲(chǔ)了ICE運(yùn)行時(shí)對(duì)于異步調(diào)用的狀態(tài)追蹤的信息。在調(diào)用begin_xxxMethod方法相關(guān)的end_xxxMethod方法時(shí),必須傳入相應(yīng)的AsyncResultPtr對(duì)象2.1 Basic Asynchronous API(4)異步方法調(diào)用中的參數(shù)Slice定義的方法參數(shù)在AMI的begin_,end_方法中有相應(yīng)的變化:double op(int inp1, string inp2, out bool outp1, out long outp2);AMI:Ice:AsyncResultPtr

11、 begin_op(Ice:Int inp1,const :std:string& inp2)Ice:Double end_op(bool& outp1, Ice:Long& outp2,const Ice:AsyncResultPtr&);注意:1)slice定義中的輸入?yún)?shù)轉(zhuǎn)移為begin_op中的唯一輸入?yún)?shù)。2)slice定義中的輸出參數(shù)作為end_op的輸出參數(shù),end_op的返回值為原slice定義的返回值。3)Begin_op返回AsyncResultPtr作為end_op的輸入?yún)?shù)。2.1 Basic Asynchronous API(5)異常處理(Exception Hand

12、ling)1)通常情況下,當(dāng)異步調(diào)用過(guò)程中發(fā)生異常,在end_xxxMethod中拋出,即使異常發(fā)生在begin_xxxMethod中。2)但有2種例外的情況:當(dāng)銷毀了當(dāng)前的Communicator后,再調(diào)用異步方法,會(huì)拋出CommunicatorDestroyedException異常。當(dāng)調(diào)用方式出錯(cuò)時(shí),拋出IceUtil:IllegalArgumentException異常(begin_,end_配對(duì)錯(cuò)誤,調(diào)用的方法參數(shù)錯(cuò)誤)2.2AsynResult類(1)AsynResult類聲明class AsyncResult : virtual public IceUtil:Shared, pr

13、ivate IceUtil:noncopyable public: virtual bool operator=(const AsyncResult&) const; virtual bool operator(const AsyncResult&) const; virtual Int getHash() const; virtual CommunicatorPtr getCommunicator() const; virtual ConnectionPtr getConnection() const; virtual ObjectPrx getProxy() const; const st

14、ring& getOperation() const; LocalObjectPtr getCookie() const; bool isCompleted() const; void waitForCompleted(); bool isSent() const; void waitForSent(); bool sentSynchronously() const;AsyncResult類由begin_op方法返回,封裝了異步調(diào)用的有關(guān)信息2.2AsynResult類(2) 方法說(shuō)明 bool operator=(const AsyncResult&) const bool operator

15、send(offset, bs); offset += bs.size();FileHandle file = open(.);FileTransferPrx ft = .;const int chunkSize = .;Ice:Int offset = 0;list results;const int numRequests = 5;while (!file.eof() ByteSeq bs; bs = file.read(chunkSize); / Send up to numRequests + 1 chunks asynchronously. Ice:AsyncResultPtr r

16、= ft-begin_send(offset, bs); offset += bs.size(); / 等待請(qǐng)求完成發(fā)送 r-waitForSent(); results.push_back(r); /超過(guò)了水位標(biāo)則阻塞等待. while (results.size() numRequests) Ice:AsyncResultPtr r = results.front(); results.pop_front(); r-waitForCompleted(); /等待剩余的請(qǐng)求完成.while (!results.empty() Ice:AsyncResultPtr r = results.fr

17、ont(); results.pop_front(); r-waitForCompleted();2.6 完成通知1.輪詢方式的完成通知1)同步方式與異步方式效率上的差距2)異步方式AsyncResult隊(duì)列控制提高傳輸效率控制內(nèi)存占用2.6 完成通知2.通用回調(diào)函數(shù)方式的完成通知相對(duì)于輪詢方式的優(yōu)點(diǎn):解除應(yīng)用邏輯與異步調(diào)用機(jī)制的耦合性。利用Ice 運(yùn)行時(shí)完成客戶端的異步處理邏輯。Slice提供的重載方法,紅色高亮部分是回調(diào)完成通知的特征。Ice:AsyncResultPtr begin_getName( Ice:Int number, const Ice:CallbackPtr& _del,

18、 const Ice:LocalObjectPtr& _cookie = 0);Ice:AsyncResultPtr begin_getName( Ice:Int number, const Ice:Context& _ctx, const Ice:CallbackPtr& _del, const Ice:LocalObjectPtr& _cookie = 0);Ice:CallbackPtr: Ice運(yùn)行時(shí)提供的回調(diào)函數(shù)智能指針,存儲(chǔ)了自定義的回調(diào)函數(shù)實(shí)例。當(dāng)發(fā)生回調(diào)時(shí),Ice運(yùn)行時(shí)會(huì)執(zhí)行回調(diào)函數(shù)對(duì)象上綁定的方法。2.6 完成通知3.自定義的回調(diào)對(duì)象示例:class MyCallback :

19、 public IceUtil:Shared public: void finished(const Ice:AsyncResultPtr& r) EmployeesPrx e = EmployeesPrx:uncheckedCast(r-getProxy(); try string name = e-end_getName(r); cout Name is: name endl; catch (const Ice:Exception& ex) cerr Exception is: ex endl; ;typedef IceUtil:Handle MyCallbackPtr;回調(diào)對(duì)象封裝了異步

20、調(diào)用實(shí)質(zhì)的業(yè)務(wù)邏輯,異步調(diào)用本身是發(fā)出非阻塞的調(diào)用請(qǐng)求,但重要的是發(fā)出了請(qǐng)求以后,應(yīng)用邏輯該如何執(zhí)行。/ 應(yīng)用程序AMI調(diào)用示例:EmployeesPrx e = .;MyCallbackPtr cb = new MyCallback;Ice:CallbackPtr d = Ice:newCallback(cb, &MyCallback:finished);e-begin_getName(99, d); 2.6 完成通知 4.回調(diào)對(duì)象的編寫(xiě)要點(diǎn)1)繼承IceUtil:Shared2) 回調(diào)對(duì)象中的回調(diào)方法,必須符合以下聲明方式:void callback_method(AsyncResultP

21、tr& r)3)回調(diào)對(duì)象中的回調(diào)方法名稱可以為合乎語(yǔ)法的任意名稱。4)回調(diào)方法中必須調(diào)用end_xxxMethod();5)回調(diào)方法必須捕獲所有可能由end_xxxMethod拋出的異常,如果遺漏了某異常,Ice運(yùn)行時(shí)默認(rèn)會(huì)在日志中記錄,但也會(huì)忽略這個(gè)異常(設(shè)置Ice.Warn.AMICallback屬性為0,可以不記錄日志)。2.6 完成通知5.應(yīng)用程序AMI調(diào)用示例:EmployeesPrx e = .;MyCallbackPtr cb = new MyCallback;Ice:CallbackPtr d = Ice:newCallback(cb, &MyCallback:finished

22、);e-begin_getName(99, d); 注意:1)Ice:newCallback輔助函數(shù),將自定義的回調(diào)對(duì)象智能指針與回調(diào)方法綁定后,返回Ice:CallbackPtr類型的對(duì)象。2)begin_xxxMethod,需要輸入一個(gè)Ice:CallbackPtr對(duì)象。2.6 完成通知6.回調(diào)中的CookieIce:AsyncResultPtr begin_getName( Ice:Int number, const Ice:CallbackPtr& _del, const Ice:LocalObjectPtr& _cookie = 0);Ice:AsyncResultPtr begin

23、_getName( Ice:Int number, const Ice:Context& _ctx, const Ice:CallbackPtr& _del, const Ice:LocalObjectPtr& _cookie = 0);Cookie對(duì)象在異步方法調(diào)用中用于begin_xxxMethod與end_xxxMethod之間傳遞信息。應(yīng)用場(chǎng)景: 用戶在界面上點(diǎn)擊產(chǎn)生大量的異步調(diào)用,當(dāng)這些異步調(diào)用完成后,每個(gè)調(diào)用需要更新不同用戶界面組件。在這種情景下,每個(gè)調(diào)用需要攜帶它所需要更新的組件信息才能完成操作。 在這種異步調(diào)用與回調(diào)函數(shù)之間需要交互的情況下,可以通過(guò)Cookie在應(yīng)用中綁定相關(guān)

24、信息。 2.6 完成通知7.Cookie的編寫(xiě)為了滿足不同的應(yīng)用場(chǎng)景,Cookie對(duì)象可以自定義。Cookie編寫(xiě)的唯一要求就是要繼承Ice:LocalObject示例:class Cookie : public Ice:LocalObjectpublic: Cookie(WidgetHandle h) : _h(h) WidgetHandle getWidget() return _h; private: WidgetHandle _h;typedef IceUtil:Handle CookiePtr;/CookiePtr cookie1 = new Cookie(widgetHandle1

25、);/ Make cookie for call to getName(42);CookiePtr cookie2 = new Cookie(widgetHandle2);/ Invoke the getName operation with different cookies.e-begin_getName(99, getNameCB, cookie1);e-begin_getName(24, getNameCB, cookie2);voidMyCallback:getName(const Ice:AsyncResultPtr& r) EmployeesPrx e = EmployeesPr

26、x:uncheckedCast(r-getProxy(); CookiePtr cookie = CookiePtr:dynamicCast(r-getCookie(); try string name = e-end_getName(r); cookie-getWidget()-writeString(name); catch (const Ice:Exception& ex) handleException(ex); 1)在應(yīng)用邏輯中創(chuàng)建了Cookie對(duì)象2)將Cookie對(duì)象傳遞給begin_getName方法3)在對(duì)應(yīng)的回調(diào)方法中重新獲得Cookie(需要向下轉(zhuǎn)型)4)從Cookie對(duì)

27、象中獲得需要的信息2.6 完成通知8.類型安全回調(diào)函數(shù)方式的完成通知(1)通用回調(diào)方法存在一些類型安全方面的隱患在回調(diào)方法中調(diào)用end_xxxMethod前必須將代理對(duì)象向下轉(zhuǎn)型為正確的代理對(duì)象類型EmployeesPrx e = EmployeesPrx:uncheckedCast(r-getProxy();調(diào)用的end_xxxMethod必須與begin_xxxMethod配對(duì)如果使用了Cookie,那么也需要將Cookie向下轉(zhuǎn)型為正確的Cookie類型。CookiePtr cookie = CookiePtr:dynamicCast(r-getCookie();在調(diào)用end_xxxMe

28、thod方法時(shí),必須要捕獲所有可能的異常。否則無(wú)法獲知調(diào)用在何時(shí)失敗Slice工具提供了一套Callback類API解決上述類型安全問(wèn)題。2.6 完成通知8.類型安全回調(diào)函數(shù)方式的完成通知(2)Slice工具與類型安全的回調(diào)Slice工具在編譯slice文件時(shí),生成一系列相關(guān)的回調(diào)函數(shù)類別,在這些自動(dòng)生成的代碼中,將類型轉(zhuǎn)換,調(diào)用end_xxxMethod等通用回調(diào)方法中的程式化方法以自動(dòng)生成的方式代替手工編程。(C+中是以模板的方式實(shí)現(xiàn)不同回調(diào)函數(shù)的模板實(shí)例)2.6 完成通知8.類型安全回調(diào)函數(shù)方式的完成通知(3)類型安全的回調(diào)函數(shù)實(shí)現(xiàn)要點(diǎn)Slice工具為slice定義的接口中的接口方法自動(dòng)

29、生成類型安全的回調(diào)類型。自定義回調(diào)類型實(shí)現(xiàn)具體的回調(diào)操作,處理業(yè)務(wù)邏輯。必須聲明一個(gè)正常情況下處理回調(diào)的方法,該方法返回void類型,參數(shù)列表與slice定義一致。當(dāng)slice返回類型不是void的時(shí)候,則第一個(gè)參數(shù)用于返回值,后續(xù)參數(shù)與slice定義中的參數(shù)列表一致。必須聲明一個(gè)異常情況下,處理異常的方法(無(wú)返回值,只有一個(gè)const Ice:Exception& ex 輸入?yún)?shù))。異步方法調(diào)用下接口方法對(duì)應(yīng)的類型安全的回調(diào)類型::Callback_Ptr:Callback_Ptr輔助回調(diào)函數(shù)用于將自定義的回調(diào)類型綁定到類型安全的回調(diào)類型實(shí)例上::newCallback_:newCallba

30、ck_2.6 完成通知9.類型安全的回調(diào)與通用回調(diào)方式的比較1)回調(diào)方法定義不同通用回調(diào):class MyCallback : public IceUtil:Shared public:/ 回調(diào)函數(shù)參數(shù)為const Ice:AsyncResultPtr& void finished(const Ice:AsyncResultPtr& r) ;類型安全的回調(diào)class MyCallback : public IceUtil:Sharedpublic: void getNameCB(int number) void failureCB(const Ice:Exception& ex)void fa

31、ilureCB(const Ice:Exception& ex) cerr Exception is: ex begin_getName(99, d); 類型安全的回調(diào):類型安全的回調(diào):MyCallbackPtr cb = new MyCallback;Callback_Employees_getNamePtr getNameCB = newCallback_Employees_getName( cb, &MyCallback:getNameCB, &MyCallback:failureCB);e-begin_getName(99, getNameCB);2.6 完成通知10.類型安全的Coo

32、kie調(diào)用方式MyCallbackPtr cb = new MyCallback;Callback_Employees_getNamePtr getNameCB = newCallback_Employees_getName( cb, &MyCallback:getNameCB,&MyCallback:failureCB);CookiePtr cookie =new Cookie(widgetHandle);e-begin_getName(99, getNameCB, cookie);class MyCallback: public IceUtil:Sharedpublic: void get

33、NameCB(const string& name, const CookiePtr& cookie) cookie-getWidget()-writeString(name);2.6 完成通知11.類型安全回調(diào)方式使用總結(jié)聲明自定義回調(diào)對(duì)象實(shí)例聲明類型安全的回調(diào)對(duì)象實(shí)例聲明類型安全回調(diào)對(duì)象實(shí)例時(shí),利用輔助函數(shù)構(gòu)造回調(diào)對(duì)象實(shí)例輔助函數(shù)中需要傳遞:自定義回調(diào)對(duì)象實(shí)例回調(diào)方法失敗處理的回調(diào)方法2.7 單路調(diào)用1)通用的回調(diào)方式由于回調(diào)類別中回調(diào)函數(shù)具有輸入?yún)?shù),void callback_method(AsyncResultPtr& r)因此是雙路調(diào)用,無(wú)法調(diào)用單路的代理對(duì)象方法。2)類型安全的回

34、調(diào)方式,通過(guò)newCallback輔助方法,在回調(diào)函數(shù)對(duì)象中只指定失敗的回調(diào)函數(shù),可以調(diào)用單路方法。示例:MyCallbackPtr cb = new MyCallback;Ice:Callback_Object_ice_pingPtr callback = Ice:newCallback_Object_ice_ping(cb,&MyCallback:failureCB);p-begin_opVoid(callback);2.8 流量控制1.流量控制的起因: 客戶端并發(fā)請(qǐng)求非常頻繁,服務(wù)端處理能力趕不上客戶端發(fā)送異步請(qǐng)求的速度??蛻舳藢⒄?qǐng)求發(fā)往客戶端Ice運(yùn)行時(shí)請(qǐng)求隊(duì)列,隊(duì)列不斷增長(zhǎng),在不加流

35、量控制的情況下,最終耗盡內(nèi)存。 2.流量控制的功能: Ice提供了一套流量控制管理的API,應(yīng)用了流量管理的api后,當(dāng)客戶端的請(qǐng)求數(shù)超過(guò)了限定的閾值,則阻塞客戶端發(fā)起的新的操作請(qǐng)求直到隊(duì)列中完成部分請(qǐng)求的處理,有剩余的空間容納入隊(duì)的請(qǐng)求。2.8 流量控制4.流量控制回調(diào)函數(shù)定義1)通用回調(diào)方式void sent(const Ice:AsyncResult&);調(diào)用情景1和情景2的判斷由程序員調(diào)用AsyncResult: sentSynchronously判斷,自行編寫(xiě)邏輯。2)類型安全的回調(diào)方式void sent(bool sentSynchronously);void sent(bool

36、sentSynchronously, const & cookie);調(diào)用情景1與情景2的判斷由Ice運(yùn)行時(shí)傳遞的sendSynchronously參數(shù)判斷。2.8 流量控制3.流量控制的編程要點(diǎn):流量控制的基本思想是自定義流量控制的方法。class MyCallback : public IceUtil:Shared public: void finished(const Ice:AsyncResultPtr&); void sent(const Ice:AsyncResultPtr&);/ 發(fā)送請(qǐng)求的方法,名字可以自定義;typedef IceUtil:Handle MyCallbackP

37、tr;情景1:當(dāng)Ice運(yùn)行時(shí)將請(qǐng)求發(fā)送到客戶端的發(fā)送端上后,由調(diào)用begin_xxxMethod的方法的線程接著調(diào)用send方法。情景2:當(dāng)Ice運(yùn)行時(shí)將請(qǐng)求入隊(duì)時(shí),則由另一線程在Ice運(yùn)行時(shí)將隊(duì)列中請(qǐng)求發(fā)送到發(fā)送端后,調(diào)用send方法。以上2種情況調(diào)用send的const Ice:AsyncResultPtr& 參數(shù)的sentSynchronously方法判斷。在send方法中對(duì)請(qǐng)求數(shù)進(jìn)行計(jì)數(shù),當(dāng)隊(duì)列的長(zhǎng)度達(dá)到高水位標(biāo),則阻塞,當(dāng)運(yùn)行時(shí)將請(qǐng)求發(fā)往發(fā)送端,則減少計(jì)數(shù)。2.9 批量調(diào)用1.批量調(diào)用的起因:對(duì)于大量的零散單路調(diào)用或數(shù)據(jù)包請(qǐng)求,服務(wù)端在處理時(shí)需要頻繁的在用戶態(tài)和內(nèi)核態(tài)之間轉(zhuǎn)換,代價(jià)非

38、常高昂。因此引入批量調(diào)用。批量調(diào)用的細(xì)節(jié)可以參考ICE手冊(cè)32.16節(jié)。2.9 批量調(diào)用2.批量調(diào)用的方法:Ice運(yùn)行時(shí)提供了將客戶端對(duì)象代理轉(zhuǎn)換為批量調(diào)用代理的方法:/ C+namespace IceProxy namespace Ice class Object : /* . */ public: /將普通代理轉(zhuǎn)換為批量調(diào)用的代理 Ice:ObjectPrx ice_batchOneway() const; Ice:ObjectPrx ice_batchDatagram() const; void ice_flushBatchRequests();/ .;2.9 批量調(diào)用3.顯式調(diào)用與隱式

39、調(diào)用 :顯式同步調(diào)用:ice_flushBatchRequests顯式異步調(diào)用:begin_ice_flushBatchRequestsend_ice_flushBatchRequests隱式調(diào)用:Ice.BatchAutoFlush=1(默認(rèn))Ice.MessageSizeMax=1MB(默認(rèn))2.10 AMI的并發(fā)Ice運(yùn)行時(shí)通常情況下由獨(dú)立的線程調(diào)用異步回調(diào)方法中的回調(diào)函數(shù)。因此在回調(diào)函數(shù)中可以使用非遞歸鎖而不怕出現(xiàn)死鎖的情況。但如果定義了流量控制回調(diào)函數(shù),則如前所述的規(guī)則,在不同的情景下,有不同的線程選擇規(guī)則。2.11 AMI的限制采用了AMI異步回調(diào),則不能采用collocated

40、optimization優(yōu)化。否則拋出CollocationOptimizationException。collocated optimization優(yōu)化 參見(jiàn)ICE手冊(cè)32.21節(jié)2.12 示例1slice文件:#ifndef HELLO_ICE#define HELLO_ICEmodule Demoexception RequestCanceledException;interface Hello/ 注意元數(shù)據(jù)定義 ami, amd idempotent void sayHello(int delay) throws RequestCanceledException; void shutd

41、own();#endif2.12 示例1intAsyncClient:run(int argc, char* argv) if(argc 1) cerr appName() : too many arguments propertyToProxy(Hello.Proxy); if(!hello) cerr argv0 : invalid proxy endl; return EXIT_FAILURE; menu(); CallbackPtr cb = new Callback(); char c;do try cout ; cin c; if(c = i) hello-sayHello(0);

42、 else if(c = d) hello-begin_sayHello(5000, newCallback_Hello_sayHello(cb, &Callback:response, &Callback:exception); else if(c = s) hello-shutdown(); else cout unknown command c endl; menu(); catch(const Ice:Exception& ex) cerr ex endl; while(cin.good() & c != x); return EXIT_SUCCESS;3. AMD編程3.1元數(shù)據(jù)標(biāo)記

43、3.2 AMD語(yǔ)言映射(C+)3.3 AMD方式下的異常3.4示例 3. AMD編程回顧AMD概述(1.3節(jié))AMD:使用 AMD 時(shí),服務(wù)器可以接收一個(gè)請(qǐng)求,然后掛起其處理,以盡快釋放分派線程。當(dāng)處理恢復(fù)、結(jié)果已得出時(shí),服務(wù)器要使用 Ice run time 提供的回調(diào)對(duì)象,顯式地發(fā)送響應(yīng)。AMD 操作通常會(huì)把請(qǐng)求數(shù)據(jù) (也就是,回調(diào)對(duì)象和操作參數(shù))放入隊(duì)列 ,供應(yīng)用的某個(gè)線程 (或線程池)隨后處理用。這樣,服務(wù)器就使分派線程的使用率降到了最低限度,能夠高效地支持?jǐn)?shù)千并發(fā)客戶。 3. 2 AMD方式的語(yǔ)言映射2. AMD的語(yǔ)言映射(C+)C+ 代碼生成器為每個(gè)AMD 操作生成以下代碼: 一個(gè)

44、抽象的回調(diào)類:實(shí)現(xiàn)用它來(lái)通知 Ice run time,操作已完成。類名規(guī)則:AMD_class_op例如,對(duì)于在接口I 中定義的名叫foo 的操作 ,對(duì)應(yīng)的類的名字是 AMD_I_foo。void ice_response();服務(wù)器可以用 ice_response 方法報(bào)告操作已成功完成。如果操作的返回類型不是 void, ice_response 的第一個(gè)參數(shù)就是返回值。與操作的out 參數(shù)對(duì)應(yīng)的參數(shù)跟在返回值后面,其次序是聲明時(shí)的次序。void ice_exception(const Ice:Exception &) :服務(wù)器可以用這個(gè)版本的 ice_exception報(bào)告用戶異?;虮?/p>

45、地異常。void ice_exception(const std:exception &):服務(wù)器可以用這個(gè)版本的 ice_exception報(bào)告標(biāo)準(zhǔn)的異常。void ice_exception():服務(wù)器可以用這個(gè)版本的 ice_exception報(bào)告未知異常 3.2 AMD方式的語(yǔ)言映射2. AMD的語(yǔ)言映射(C+)(2)分派方法:其名字有后綴 _async。這個(gè)方法的返回類型是 void第一個(gè)參數(shù)是一個(gè)智能指針,指向上面描述的回調(diào)類的一個(gè)實(shí)例。其他的參數(shù)由操作的各個(gè) in參數(shù)組成,次序是聲明時(shí)的次序. 3.2 AMD方式的語(yǔ)言映射interface I amd int foo(short

46、 s, out long l);下面是為操作foo 生成的回調(diào)類:class AMD_I_foo : public . public:void ice_response(Ice:Int, Ice:Long);void ice_exception(const Ice:Exception &);void ice_exception(const std:exception &);void ice_exception();下面是為操作foo 的異步調(diào)用生成的分派方法:void foo_async(const AMD_I_fooPtr &, Ice:Short); 3. 3 AMD的異常傳遞 在兩種處理

47、上下文中, AMD 操作的邏輯實(shí)現(xiàn)可能需要報(bào)告異常:分派線程 ( 也就是,接收調(diào)用的線程),以及響應(yīng)線程 (也就是,發(fā)送響應(yīng)的線程 )。 盡管建議你用回調(diào)對(duì)象來(lái)把所有異常報(bào)告給客戶,實(shí)現(xiàn)拋出異常也是合法的,但只能在分派線程中拋出。 Ice run time 無(wú)法捕捉從響應(yīng)線程拋出的異常;應(yīng)用的運(yùn)行時(shí)環(huán)境將決定怎樣處理這樣的異常。因此,響應(yīng)線程必須確保抓住所有異常,并用回調(diào)對(duì)象發(fā)送適當(dāng)?shù)捻憫?yīng)。否則,如果響應(yīng)線程被未捕捉的異常終止,請(qǐng)求就可能不會(huì)完成,客戶將無(wú)限期地等待響應(yīng)。 3. 4 示例Slice定義interface Hello ami, amd idempotent void sayHel

48、lo(int delay) throws RequestCanceledException; void shutdown();3. 4 示例服務(wù)端聲明文件代碼:#include #include class HelloI : virtual public Demo:Hellopublic: HelloI(const WorkQueuePtr&); / 分派函數(shù) virtual void sayHello_async(const Demo:AMD_Hello_sayHelloPtr&, int, const Ice:Current&); virtual void shutdown(const I

49、ce:Current&);private: WorkQueuePtr _workQueue;3. 4 示例服務(wù)端實(shí)現(xiàn)文件代碼:HelloI:HelloI(const WorkQueuePtr& workQueue) : _workQueue(workQueue)voidHelloI:sayHello_async(const Demo:AMD_Hello_sayHelloPtr& cb, int delay, const Ice:Current&) if(delay = 0) cout Hello World! ice_response(); else _workQueue-add(cb, de

50、lay); voidHelloI:shutdown(const Ice:Current& curr) cout Shutting down. destroy(); curr.adapter-getCommunicator()-shutdown();3. 4 示例服務(wù)端實(shí)現(xiàn)文件代碼:intAsyncServer:run(int argc, char* argv) if(argc 1) cerr appName() : too many arguments createObjectAdapter(Hello); _workQueue = new WorkQueue(); Demo:HelloPtr

51、 hello = new HelloI(_workQueue); / Demo:HelloPtr hello = new HelloI(_workQueue); /定義服務(wù)端定義服務(wù)端servrantservrant adapter-add(hello, communicator()-stringToIdentity(“hello”); / / 將將serverantserverant加入適配器加入適配器 / / 啟動(dòng)工作隊(duì)列啟動(dòng)工作隊(duì)列 _workQueue-start();_workQueue-start(); adapter-activate(); / communicator()-waitForShutdown(); _workQueue-getThreadControl().join();/等待工作隊(duì)列停止 r

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論