• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 2, 文章 - 73, 評(píng)論 - 60, 引用 - 0
            數(shù)據(jù)加載中……

            [轉(zhuǎn)載]Active Scheduler & Active Object,活動(dòng)規(guī)劃器和活動(dòng)對(duì)象

            活動(dòng)規(guī)劃器 (Active Scheduler)

            由于使用多線程來處理異步請(qǐng)求比較消耗系統(tǒng)資源,所以symbian 使用了活動(dòng)對(duì)象(Active Object)來解決異步請(qǐng)求的問題。
            活動(dòng)規(guī)劃器(active scheduler)用于處理由活動(dòng)對(duì)象提出的異步請(qǐng)求。它檢測(cè)活動(dòng)對(duì)象提出的異步請(qǐng)求,并安排活動(dòng)對(duì)象的請(qǐng)求完成事件的執(zhí)行順序。活動(dòng)規(guī)劃器僅用一個(gè)事件處理線程來規(guī)劃各個(gè)活動(dòng)對(duì)象提出的事件請(qǐng)求,所以它要比多線程實(shí)現(xiàn)異步請(qǐng)求占用更少的資源。
            一個(gè)活動(dòng)規(guī)劃器通常對(duì)應(yīng)到一個(gè)線程,CActiveScheduler 類的靜態(tài)方法通常都是針對(duì)當(dāng)前線程中對(duì)象的操作。
            在程序中使用活動(dòng)對(duì)象時(shí),首先應(yīng)該創(chuàng)建一個(gè)活動(dòng)規(guī)劃器對(duì)象,并把它安裝到當(dāng)前線程,也就是把活動(dòng)規(guī)劃器和當(dāng)前線程關(guān)聯(lián)。 CActiveScheduler::Install()方法可以把活動(dòng)規(guī)劃器安裝到當(dāng)前線程, CActiveScheduler::Current() 方法可以獲取和當(dāng)前線程關(guān)聯(lián)的活動(dòng)規(guī)劃器。如:

            CActiveScheduler::Install(CAtv)
            CActiveScheduler* sco2 =CActiveScheduler::Current();

            Add()方法可以把活動(dòng)對(duì)象添加到活動(dòng)規(guī)劃器中,這樣活動(dòng)規(guī)劃器就可以處理活動(dòng)對(duì)象所提出的異步請(qǐng)求,當(dāng)異步請(qǐng)求完成事件發(fā)生時(shí)調(diào)用活動(dòng)對(duì)象的RunL()方法。
            活動(dòng)規(guī)劃器的 Add() 方法把指定的活動(dòng)對(duì)象添加到當(dāng)前的活動(dòng)規(guī)劃器中。但是在某些時(shí)候可能需要?jiǎng)h除在活動(dòng)規(guī)劃器中的活動(dòng)對(duì)象:如果活動(dòng)對(duì)象被銷毀,那么同時(shí)活動(dòng)對(duì)象就在活動(dòng)規(guī)劃器中被刪除了,另外使用活動(dòng)規(guī)劃器的Deque()方法也可以把活動(dòng)對(duì)象從活動(dòng)規(guī)劃器中刪除。
            在調(diào)用Add()方法之前必須確認(rèn)活動(dòng)規(guī)劃器已經(jīng)安裝到當(dāng)前線程,否則將發(fā)生E32USER-CBase 44 panic。Add()方法包括一個(gè)CActive型的參數(shù), 這是一個(gè)指向活動(dòng)對(duì)象的指針,在調(diào)用Add()方法時(shí),這個(gè)指針不可以為 NULL,否則函數(shù)發(fā)生 E32USER-CBase 48 panic。另外與要注意的是,在使用Add()方法之前確認(rèn)活動(dòng)對(duì)象是否已經(jīng)添加到活動(dòng)規(guī)劃器中,如果這個(gè)對(duì)象已經(jīng)添加到活動(dòng)規(guī)劃器中那么將發(fā)生E32USER-CBase 41 panic。
            CActiveScheduler::Start()方法啟動(dòng)一個(gè)在當(dāng)前活動(dòng)規(guī)劃器控制下的的循環(huán)等待。而CActiveScheduler::Stop()則可以終止活動(dòng)規(guī)劃器的循環(huán)等待。活動(dòng)規(guī)劃器實(shí)際上是構(gòu)建了一個(gè)事件處理的框架,它在循環(huán)中使用User::WaitForAnyRequest()等待活動(dòng)對(duì)象的異步請(qǐng)求,當(dāng)請(qǐng)求事件完成時(shí),就調(diào)用一該請(qǐng)求事件相關(guān)的活動(dòng)對(duì)象的RunL()方法。活動(dòng)對(duì)象調(diào)用RunL()時(shí)把它放在TRAP下,這樣即使RunL()函數(shù)發(fā)生Leave活動(dòng)對(duì)象也有可以對(duì)它處理,執(zhí)行一些必要的內(nèi)存清理。當(dāng)RunL()發(fā)生異常退出之后,首先進(jìn)入活動(dòng)對(duì)象的RunError()方法,這個(gè)方法是一個(gè)需方法,有一個(gè)默認(rèn)實(shí)現(xiàn),并返回一個(gè)整型的值,如果返回的整形值不是KEeeNone,那么活動(dòng)規(guī)劃器將調(diào)用自己的Error()方法。Error()方法也有一個(gè)默認(rèn)的實(shí)現(xiàn):發(fā)生一個(gè)E32USER-CBase 47 panic。

            活動(dòng)對(duì)象(Active Object)

            CActive類是活動(dòng)對(duì)象(Active Object)的核心類,所有的活動(dòng)對(duì)象類應(yīng)該從這個(gè)類繼承。在CActive 中,封裝了兩個(gè)功能:一個(gè)是向異步服務(wù)提供者發(fā)出異步請(qǐng)求;另外一個(gè)是處理請(qǐng)完成事件。一個(gè)應(yīng)用程序中可以包含若干個(gè)活動(dòng)對(duì)象,并且是它們的都在活動(dòng)規(guī)劃器(active scheduler)的控制下運(yùn)行。
            活動(dòng)對(duì)象應(yīng)該包括一個(gè)和請(qǐng)求函數(shù)相關(guān)連的請(qǐng)求對(duì)象,請(qǐng)求函數(shù)是專門用于完成異步請(qǐng)求的,由于帶有請(qǐng)求函數(shù)的對(duì)象提供了異步服務(wù),所以在SDK的文檔里又把他們叫做異步服務(wù)提供者(asynchronous service provider)。這里可以舉一個(gè)簡(jiǎn)單的例子,RTimer中包括了一些請(qǐng)求函數(shù),如After()、At()等。所以RTimer型的對(duì)象是一個(gè)異步服務(wù)提供者。所以在活動(dòng)對(duì)象中,通常會(huì)有一個(gè)服務(wù)提供者成員,它的作用是提出一個(gè)異步請(qǐng)求,并異步完成他們的請(qǐng)求。
            活動(dòng)對(duì)象的 RunL() 方法用于處理活動(dòng)對(duì)象的請(qǐng)求完成事件。活動(dòng)對(duì)象類作為CActive類的派生類,它必須實(shí)現(xiàn)RunL()方法。如果有業(yè)務(wù)邏輯需要,RunL()可以發(fā)出另外一個(gè)新的異步請(qǐng)求。當(dāng)請(qǐng)求結(jié)束事件發(fā)生時(shí),這個(gè)函數(shù)被活動(dòng)規(guī)劃器調(diào)用,也就是說,在活動(dòng)規(guī)劃器的WaitForAnyRequest()函數(shù)結(jié)束以后RunL()函數(shù)被調(diào)用。WaitForAnyRequest()實(shí)際上是對(duì)User::WaitForAnyRequest()的調(diào)用。
            在調(diào)用活動(dòng)對(duì)象的RunL方法前,活動(dòng)規(guī)劃器需要確定,哪一個(gè)活動(dòng)對(duì)象擁有最高優(yōu)先權(quán),然后標(biāo)記該對(duì)象的請(qǐng)求作為請(qǐng)求完成事件。這個(gè)優(yōu)先權(quán)是在活動(dòng)對(duì)象構(gòu)造的時(shí)候指定的。RunL運(yùn)行在活動(dòng)規(guī)劃器所設(shè)定的TRAP中,如果RunL在執(zhí)行過程中發(fā)生leave那么,那么活動(dòng)規(guī)劃器將調(diào)用RunError()方法。一旦調(diào)用了活動(dòng)規(guī)劃器的 Start方法,那么所有的用戶代碼將運(yùn)行在活動(dòng)規(guī)劃器的某個(gè)活動(dòng)對(duì)象的RunL()函數(shù)或RunError函數(shù)下。
            活動(dòng)對(duì)象 RunError() 方法用于處理請(qǐng)求結(jié)完成事件處理函數(shù)RunL() 的異常退出(Leave)。如果活動(dòng)對(duì)象的RunL()函數(shù)發(fā)生Leave,那么活動(dòng)規(guī)劃器將調(diào)用活動(dòng)對(duì)象的RunError方法。這樣這個(gè)發(fā)生錯(cuò)誤的活動(dòng)對(duì)象就可以完成一些必要的內(nèi)存清理。如果有派生類實(shí)現(xiàn)了這個(gè)方法,那么就應(yīng)該對(duì)可能的 leave 做出處理,并返回KErrNone;如果返回了其他的錯(cuò)誤碼,那么CActiveScheduler類的Error()將被調(diào)用。
            RunError() 方法的默認(rèn)實(shí)現(xiàn)返回一個(gè)異常退出碼,而一旦發(fā)生leave這個(gè)異常退出碼是一個(gè)非KErrNone的值,這樣可以認(rèn)為:一般情況下,活動(dòng)對(duì)象的RunL()方法如果發(fā)生leave,那么CActiveScheduler類的Error()將被調(diào)用。
            注意:如果活動(dòng)對(duì)象用于錯(cuò)誤處理,那么在他的派生類中應(yīng)該提供一個(gè)比較好的CActiveScheduler Error函數(shù),以便處理那些錯(cuò)誤。
            活動(dòng)對(duì)象的SetActive()方法用于向活動(dòng)規(guī)劃器提交一個(gè)異步請(qǐng)求。派生類應(yīng)該在請(qǐng)求發(fā)出以后調(diào)用這個(gè)方法。活動(dòng)對(duì)象也可以通過一定的方法來取消請(qǐng)求,但是這里需要說明的是,取消請(qǐng)求只是讓請(qǐng)求提前完成。關(guān)于異步請(qǐng)求取消可以使用Cancel()方法。

            請(qǐng)求狀態(tài)(TRequestStatus)

            服務(wù)提供者為了完成服務(wù),需要有一個(gè)如何完成服務(wù)的信息。TRequestStatus 類的對(duì)象用于存放為服務(wù)提供者定制的請(qǐng)求完成狀態(tài)。當(dāng)線程提出請(qǐng)求時(shí),例如RTimer 的After()請(qǐng)求,請(qǐng)求狀態(tài)對(duì)象被作為參數(shù)傳遞到請(qǐng)求函數(shù)中。服務(wù)完成以后,服務(wù)提供者發(fā)送信號(hào)給服務(wù)請(qǐng)求對(duì)象的請(qǐng)求信號(hào)量并在請(qǐng)求對(duì)象中保存一個(gè)完成碼,通常這個(gè)完成碼的值是KErrNone或者是其他系統(tǒng)定義的錯(cuò)誤碼。TRequestStatus 類是密封類,不再被繼承。

            活動(dòng)規(guī)劃器和活動(dòng)對(duì)象協(xié)同工作

            這里的代碼和附件中的例子一致,可以下載例子直接在VC6++中調(diào)試。活動(dòng)規(guī)劃器和活動(dòng)對(duì)象的的協(xié)同工作過程如下。首先應(yīng)該創(chuàng)建一個(gè)與當(dāng)前線程相關(guān)的活動(dòng)規(guī)劃器:

            CATV* sco = new(ELeave) CATV();
            // 推入清理?xiàng)?br>CleanupStack::PushL(sco);
            // 把 sco 活動(dòng)規(guī)劃器安裝為當(dāng)前線程的活動(dòng)對(duì)象
            // 安裝以后,sco 活動(dòng)對(duì)象專門處理當(dāng)前線程的請(qǐng)求事件
            CActiveScheduler::Install(sco);

            接著創(chuàng)建一個(gè)活動(dòng)對(duì)象,TmCount類是一個(gè)從CActive類派生的活動(dòng)對(duì)象類。

            TmCount* timeCount = TmCount::NewLC();

            然后可以從NewLC()方法中看到活動(dòng)對(duì)象構(gòu)造的具體細(xì)節(jié):

            TmCount* TmCount::NewLC()
            {
            console->Printf(_L("NewLC\n"));
            // 使用 C++默認(rèn)構(gòu)造函數(shù)構(gòu)造
            TmCount* result = new (ELeave) TmCount();
            // 把活動(dòng)對(duì)象推入清理粘
            CleanupStack::PushL( result );
            // 調(diào)用兩階段構(gòu)造函數(shù),構(gòu)造活動(dòng)對(duì)象內(nèi)部成員
            result->ConstructL();
            // 返回活動(dòng)對(duì)象指針
            return result;
            };

            在這個(gè)默認(rèn)的構(gòu)造函數(shù)中,還調(diào)用了默認(rèn)的C++構(gòu)造函數(shù),這個(gè)比較關(guān)鍵,因?yàn)檎窃谶@個(gè)構(gòu)造函數(shù)中,把活動(dòng)對(duì)象添加到了活動(dòng)對(duì)象,在這個(gè);函數(shù)中,還可以定義活動(dòng)對(duì)象的優(yōu)先權(quán)限:

            TmCount::TmCount():CActive(0) // 這里可以設(shè)置活動(dòng)對(duì)象的優(yōu)先級(jí)
            {
            // 把自己加入活動(dòng)規(guī)劃器
            iTimeCounter=1;
            CActiveScheduler::Add(this);

            };

            在ConstructL()中,則獲得了一個(gè)記時(shí)器句柄
            void TmCount::ConstructL()
            {
            // 初始化計(jì)數(shù)器和定時(shí)器
            iTimeCounter = 0;
            User::LeaveIfError(iTimer.CreateLocal());
            console->Printf(_L("ConstructL\n"));
            };

            這樣,活動(dòng)對(duì)象構(gòu)造完成。接著,程序調(diào)用活動(dòng)對(duì)象的請(qǐng)求函數(shù)。

            timeCount->StartL(1);

            在活動(dòng)對(duì)象的請(qǐng)求函數(shù)中:

            // 活動(dòng)對(duì)象的請(qǐng)求函數(shù)
            void TmCount::StartL(TInt mT)
            {
            // 將請(qǐng)求傳遞給異步服務(wù)提供者,
            // 異步服務(wù)提供者,調(diào)用請(qǐng)求函數(shù),
            // 這里需要注意iStatus 這個(gè)參數(shù),它是一個(gè)請(qǐng)求狀態(tài)對(duì)象。
            // 設(shè)定定時(shí)器狀態(tài)為每隔mTime秒鐘狀態(tài)完成一次
            iTimer.After(iStatus, 10000 * 100 * mT);
            // 在調(diào)用異步請(qǐng)求函數(shù)之后調(diào)用SteActive()方法,提交異步請(qǐng)求
            SetActive();
            };

            異步服務(wù)提供者處理請(qǐng)求,當(dāng)請(qǐng)求處理完成以后,它生成一個(gè)事件。活動(dòng)規(guī)劃器不斷的檢查是否有請(qǐng)求完成(是否有請(qǐng)求完成事件發(fā)生),如果有請(qǐng)求完成,那么調(diào)用與該請(qǐng)求相關(guān)聯(lián)的活動(dòng)對(duì)象的RunL()方法:

            void TmCountTwo::RunL()
            {
            // 計(jì)數(shù)器+1以后繼續(xù)提交延時(shí)請(qǐng)求事件
            console->Printf(_L("[2]The Count is ->>%d\n"), iTimeCounter++);
            // 再次提出異步請(qǐng)求
            StartL(1);
            };

            在這個(gè)方法中又提出了一次異步請(qǐng)求,并使計(jì)數(shù)器值增加。如果條件符合則可以不再讓活動(dòng)對(duì)象提出異步請(qǐng)求,這是一個(gè)修改后的RunL():

            void TmCount::RunL()
            {
            // 計(jì)數(shù)器+1以后繼續(xù)提交延時(shí)請(qǐng)求事件
            console->Printf(_L("[1]The Count is ->>%d\n"), iTimeCounter++);
            // 當(dāng)記數(shù)器值大于等于10時(shí),不再提出異步請(qǐng)求。
            if (iTimeCounter<10)
            {
            StartL(1);
            }
            else
            {
            //取消請(qǐng)求
            Cancel();
            }
            //User::Leave(9);
            };

            如果RunL()在運(yùn)行過程中發(fā)生錯(cuò)誤,則RunError()被調(diào)用,以下是RunEror()方法:

            TInt TmCount::RunError(TInt aError)
            {
            console->Printf(_L("[1]Error\n"));
            //console->Getch();
            return 7;
            };

            如果RunError()方法返回了一個(gè)非KErrNone的值那么活動(dòng)規(guī)劃器的Error方法將被調(diào)用。
            class CATV :public CActiveScheduler
            {
            public :
            IMPORT_C void Error(TInt anError) const;

            };

            void CATV::Error(TInt anError) const
            {
            console->Printf(_L("Error:%d\n"),anError);
            //CATV::Stop();
            };

            posted on 2007-10-12 18:43 郭天文 閱讀(880) 評(píng)論(0)  編輯 收藏 引用 所屬分類: S60

            久久综合久久性久99毛片| 久久人妻少妇嫩草AV蜜桃| 久久精品中文无码资源站| 亚洲精品无码久久久久| 久久精品人人槡人妻人人玩AV| 久久久一本精品99久久精品66| 久久久久国产一级毛片高清版| 精品无码久久久久久久久久| 久久久久亚洲AV无码专区网站| 模特私拍国产精品久久| 久久国产色AV免费看| 色综合久久综精品| 97久久婷婷五月综合色d啪蜜芽| 久久久噜噜噜久久中文福利| 国产午夜福利精品久久| 久久久久久精品久久久久| 久久综合丝袜日本网| 一本一道久久综合狠狠老| 久久亚洲高清综合| 国产精品一久久香蕉国产线看观看 | 久久国产精品免费一区二区三区| 超级97碰碰碰碰久久久久最新| 久久精品国产第一区二区三区 | 亚洲国产日韩欧美综合久久| 午夜不卡久久精品无码免费| 欧美国产精品久久高清| 青青青青久久精品国产| 久久精品无码专区免费东京热| 亚洲精品成人久久久| 久久久久黑人强伦姧人妻| 久久亚洲国产精品一区二区| 国内精品久久久人妻中文字幕| 久久久久亚洲精品日久生情 | 久久99精品久久久久久野外 | 久久久久精品国产亚洲AV无码| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 久久e热在这里只有国产中文精品99| 九九精品99久久久香蕉| 漂亮人妻被黑人久久精品| 97精品依人久久久大香线蕉97 | 久久se精品一区二区影院 |