CurveSoft Studio

奔三之年开始北漂的上海女婿的IT人生

« 如何得到程序路径Symbian OS安全体系 »

RThread

RThread

From Forum Nokia Wiki


ID   Creation date March 20, 2008
Platform S60 3rd Edition Tested on devices Nokia N95
Category Symbian C++ Subcategory Code Examples


Keywords (APIs, classes, methods, functions): RThread, CTrapCleanup, CActiveScheduler, CPeriodic

Overview

In this RThread example we show how to:

  • Create simple CMyThread thread class that runs RThread
  • How to listen thread execution
  • How add cleanup stack support for threads
  • How add active scheduler support for threads

Our CMyThread thread runs CPeriodic timer.


MMP file

RThread needs

LIBRARY euser.lib

Header

#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;
};

Source

#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;
}

Running the CMyThread

Place CMyThread into class member variable and execute it

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

When thread is executed and it calls its observer that is reference parameter in CMyThread::NewL(*this)

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

Postconditions

Thread created and executed.

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

日历

最新评论及回复

最近发表

图标汇集

  • MoStar 手机游戏社区
  • Firefox - Rediscover the Web
  • RainbowSoft Studio Z-Blog
  • 本站支持WAP访问
  • 订阅本站的 ATOM 1.0 新闻聚合
  • 订阅本站的 RSS 2.0 新闻聚合
  • 点击这里给我发消息
  • Post your Page Rank with WebmasterEyes.com

Powered By Z-Blog 1.7 Laputa Build 70216

沪ICP备05043298号