Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

RThread简介

From Wiki
Jump to: navigation, search
Article Metadata

兼容于
平台: S60 3rd Edition FP1
S60 3rd Edition (initial release)

文章
翻译:
hoolee
最后由 hamishwillee 在 30 May 2013 编辑
  • 详细描述

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;
}Running the CMyThread


  • 运行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
}
  • 后记

这个线程将被创建并执行

This page was last modified on 30 May 2013, at 04:35.
267 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×