愛悠閑 > symbian流媒體入門之--《RThread使用的簡單例子》

symbian流媒體入門之--《RThread使用的簡單例子》

分類: symbian  |  標簽: symbian,thread,class,object,library,delete  |  作者: zhangheng0423 相關  |  發布日期 : 2015-12-04  |  熱度 : 251°

原文出處:鏈接地址

 

開發伙伴平臺

 

S60 3rd Edition, FP1

 

詳細描述

 

RThread示例顯示了如何:

1、生成一個簡單的CMyThread線程類,可以運行RThread

2、如何監聽線程的執行

3、如何增加線程的清除棧

4、如何增加線程的活動調度支持

這里CMyThread線程負責運行了CPeriodic timer

 

MMP文件

 

RThread需要

LIBRARY euser.lib

 

頭文件

 

 #include <e32base.h>
 
class MThreadExecuteObserver
    {
    public:
        virtual void ThreadExecuted(TInt aError) = 0;
    };
 
class CMyThread : public CActive, public MThreadExecuteObserver
    {
    public:
        static CMyThread* NewL(MThreadExecuteObserver& aObserver);
        virtual ~CMyThread();
        TInt ExecuteThread(TTimeIntervalMicroSeconds32 anInterval);
        inline TTimeIntervalMicroSeconds32 Interval(){return iInterval;};
 
    private: // From MThreadExecuteObserver
        void ThreadExecuted(TInt aError);
 
    private: // From CActive
        void RunL();
        void DoCancel();
 
    private:
        CMyThread(MThreadExecuteObserver& aObserver);
        void ConstructL();
        void CreateThreadL();
        TInt StartThread();
        static TInt ThreadFunction(TAny* aParams);
        static TInt PeriodicTick(TAny* aObject);
 
    private:
        MThreadExecuteObserver&         iObserver;
        RThread                         iThread;
        TTimeIntervalMicroSeconds32     iInterval;
    };

 

源文件

 #include "CMyThread.h"
 
const TInt KStackSize = 16384;
_LIT(KExecThreadBaseName, "CMyThread");
 
// Global thread id counter for making CMyThread thread names unique.
// This is achieved by appending counter to the end of thread name and
// incrementing counter value for next thread.
// This is writable static data.
TInt g_thread_id_counter = 0;
 
LOCAL_C void GenerateUniqueName(TDes& aResult, CMyThread* aExecutor)
    {
    _LIT(KHexFormat, "_0x%x");
    _LIT(KCounterFormat, "_%d");
    aResult.Copy(KExecThreadBaseName);
    aResult.AppendFormat(KHexFormat, aExecutor);
    g_thread_id_counter++;
    aResult.AppendFormat(KCounterFormat, g_thread_id_counter);
    }
 
CMyThread* CMyThread::NewL(MThreadExecuteObserver& aObserver)
    {
    CMyThread* self = new (ELeave) CMyThread(aObserver);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
    }
 
CMyThread::CMyThread(MThreadExecuteObserver& aObserver)
    : CActive(EPriorityStandard),iObserver(aObserver)
    {
    CActiveScheduler::Add(this);
    }
 
CMyThread::~CMyThread()
    {
    Cancel();
    iThread.Close();
    }
 
void CMyThread::ConstructL()
    {
    }
 
TInt CMyThread::ExecuteThread(TTimeIntervalMicroSeconds32 anInterval)
    {
    TInt ret = KErrNone;
    iInterval = anInterval;
    TRAP(ret,CreateThreadL());
    if (!ret)
        {
        ret = StartThread();
        }
    return ret;
    }
 
TInt CMyThread::StartThread()
    {
    TInt ret = KErrNone;
    if(!IsActive())
        {
        // Requests notification when this thread dies
        // normally or otherwise
        iThread.Logon(iStatus);
        SetActive();
        iThread.Resume();
        }
    else
        {
        ret = KErrOverflow;
        }
    return ret;
    }
 
void CMyThread::ThreadExecuted(TInt aError)
    {
    iObserver.ThreadExecuted(aError);
    }
 
void CMyThread::RunL()
    {
    iObserver.ThreadExecuted(iStatus.Int());
    }
 
void CMyThread::DoCancel()
    {
    iThread.LogonCancel(iStatus);
    iThread.Kill(KErrCancel);
    }
 
void CMyThread::CreateThreadL()
    {
    HBufC* threadName = HBufC::NewLC(KMaxFileName);
    TPtr ptr = threadName->Des();
    GenerateUniqueName(ptr, this);
 
    User::LeaveIfError(iThread.Create(
                        *threadName,
                        CMyThread::ThreadFunction,
                        KStackSize,
                        NULL,
                        this));
 
    CleanupStack::PopAndDestroy(threadName);
    }
 
TInt CMyThread::ThreadFunction(TAny* aParams)
    {
    // 1. Add cleanup stack support.
    CTrapCleanup* cleanupStack = CTrapCleanup::New();
 
    // 2. Get pointer to thread host
    CMyThread* host = (CMyThread*)aParams;
 
    TRAPD(err,
        // 3. Add support for active objects
        CActiveScheduler* activeScheduler = new (ELeave) CActiveScheduler;
        CleanupStack::PushL(activeScheduler);
        CActiveScheduler::Install(activeScheduler);
 
        // 4. Create and start CPeriodic class that is executed in this thread
        CPeriodic* periodic = CPeriodic::NewL(CActive::EPriorityLow);
        CleanupStack::PushL(periodic);
        periodic->Start(host->Interval(),host->Interval(),
        TCallBack(host->PeriodicTick, host));
 
        // NOTE: When adding CActiveScheduler support for threads we have to
        // add atleast one active object in it or it fails on
        // CActiveScheduler::Start().
        // CPeriodic is derived from CActive active object so that is good for
        // this example.
 
        // 5. --> Thread execution starts
        CActiveScheduler::Start();
        // 6. --> Thread execution ends (waiting for CActiveScheduler::Stop())
 
        CleanupStack::PopAndDestroy(periodic);
        CleanupStack::PopAndDestroy(activeScheduler);
        );
 
    host->ThreadExecuted(err);
    delete cleanupStack;
    return KErrNone;
    }
 
TInt CMyThread::PeriodicTick(TAny* aObject)
    {
    CMyThread* mythread = (CMyThread*)aObject;
    if (mythread)
        {
        // Thread is executed once so time to stop it
        CActiveScheduler::Stop();
        // After this execution continues from CActiveScheduler::Start()
        }
    // Does not continue again
    // Note: Does not work with this CPeriodic class
    return EFalse;
    }

 

運行CMyThread

將CMyThread作為類成員變量,然后執行它

TTimeIntervalMicroSeconds32 time(100);
iMyThread = CMyThread::NewL(*this);
iMyThread->ExecuteThread(time);

當線程執行時,它會調用作為引用參數傳入CMyThread::NewL(*this)的observer

void CYourClass::ThreadExecuted(TInt aError)
    {
    // Will be called after thread execution
    }



快乐彩中奖说明