Basic Of Multi-Threads

news/2024/7/8 4:19:00 标签: basic, semaphore, user, math, random, math.h
1] RHandleBase 类

作为多线程,首先要考虑到的是 RThread 类。RThread 类从 RHandleBase 类继承,所以它首先是一个对象的句柄(a handle of an object),包括了 Close(), Duplicate(), FullName(), Handle(), HandleInfo(), Name(), RHandleBase(), SetHandle(), SetHandleNC() 方法。这个类是一个抽象类,没有自己的实例,通常都是作为其他类的基类使用,例如 RSemaphore, RThread, RProcess, RCriticalSection 等。RTimer 类是从RHandleBase 继承的一个类,可以通过这个类,来说明一些 RHandleBase 的一些问题 。 以下是代码。

#include <e32base.h>
#include <e32cons.h>

// 定义本地数据
LOCAL_D CConsoleBase* console;
LOCAL_C void NewCsoLC();
LOCAL_D TInt err;

//全局函数,被 E32 调用的主函数,
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
CTrapCleanup* cup=CTrapCleanup::New();
TRAP(err,NewCsoLC());
delete cup;
__UHEAP_MARKEND;
return 0;
}

LOCAL_C void NewCsoLC()
{
__UHEAP_MARK;
_LIT(TITLE,"RHandleBase Demo");
TSize Ts=TSize();
Ts.SetSize(-1,-1);
console=Console::NewL(TITLE,Ts);
CleanupStack::PushL(console);


RTimer RTM;
//创建一个与系统计时器相关联的句柄
RTM.CreateLocal();

//RTM.Close();
//RTM.CreateLocal();


// 获得与当前句柄相关联对象的 handle-number
console->Printf(_L("HandleNum:"));
console->Printf(_L("%d"),RTM.Handle());
console->Printf(_L(" "));

// 设置与当前句柄相关联对象的 handle-number
// 这个值似乎不能乱设,否则将导致系统异常,具体细节不甚清楚
//RTM.SetHandle(180000000);
//RTM.SetHandleNC(18000000000);
//console->Printf(_L("HandleNum:"));
//console->Printf(_L("%d"),RTM.Handle());
//console->Printf(_L(" "));


// 获得句柄全名
console->Printf(_L("FullName:"));
console->Printf(RTM.FullName());
console->Printf(_L(" "));

// 获得句名称
console->Printf(_L("Name:"));
console->Printf(RTM.Name());
console->Printf(_L(" "));

// HandleInfo() 方法需要传入一个 THandleInfo 型的指针
THandleInfo* Hif;
RTM.HandleInfo(Hif);
// 通过这个 Hif 指针可以获取和设置与句柄相关的系统对象的信息。
console->Printf(_L("iNumOpenInProcess:%d "),Hif->iNumOpenInProcess);
console->Printf(_L("iNumOpenInThread:%d "),Hif->iNumOpenInThread);
console->Printf(_L("iNumProcesses:%d "),Hif->iNumProcesses);
console->Printf(_L("iNumThreads:%d "),Hif->iNumThreads);

Hif->iNumOpenInProcess=8;
Hif->iNumOpenInThread=9;
Hif->iNumProcesses=90;
Hif->iNumThreads=4;

console->Printf(_L("iNumOpenInProcess:%d "),Hif->iNumOpenInProcess);
console->Printf(_L("iNumOpenInThread:%d "),Hif->iNumOpenInThread);
console->Printf(_L("iNumProcesses:%d "),Hif->iNumProcesses);
console->Printf(_L("iNumThreads:%d "),Hif->iNumThreads);

//关闭句柄
/*
这个操作对与句柄相关的内核对象也有一定作用。
与句柄相关联的对象似乎是一个引用计数对象,
当外部不再有对该内核对象打开的引用时,Close()方法可以销毁这个内核对象
*/
RTM.Close();
console->Printf(_L("Press to end "));

console->Getch();
CleanupStack::PopAndDestroy();
__UHEAP_MARKEND;
}

[2] RThread 类

在这个类中,需要了解他主要的几个方法。

1.Create()方法:这个方法有四个版本的重载函数,但是基本的参数也就这些:

参 数描 述
const TDesC& aName线程的名称
TThreadFunction aFunction一个指向函数的指针,当线程被恢复时调用该函数,也就是线程最初预定运行的函数。
TInt aStackSize新线程的 Stack 大小,它不可以为负值,否则函数将发生 USER 109 panic
TAny* aPtr一个指向数据的指针,这些数据是线程函数运行所需要的,如果线程函数不需要参数,则可以把该指针置为NULL
TInt aHeapMinSize 新线程 heap 的最小值, 这个值必须不小于在 e32std.h 中定义的 KMinHeapSize,否则函数将发生 USER 110 panic
TInt aHeapMaxSize新线程的 heap 的最大值, 它必须不小于 aHeapMinSize,否则函数将个发生 USER 111 panic
TOwnerType aType它是一个枚举型变量,指明要创建的线程是属于进程还是线程,如果这个值没有被指定,那么将默认 EOwnerProcess,也就是说,新的线程是属于进程的。
RProcess* aProcess指明当前线程所属的进程
RLibrary* aLibrary指明线程函数所在的 DLL

2.Resume() 方法:这个方法使创建好的线程处于执行状态。刚刚创建好的线程是处在暂停状态的,Resume() 方法使线程从暂停态转到执行态。

3.Kill() 方法:以指定的原因代码退出指定线程;它与 User::Exit() 的功能类似。

[3] RSemaphore

Semaphore 应该是信号量的意思,这个应该是《操作系统》里的知识吧。信号量(semaphore)是一个内核对象,RSemaphore类提供了对 semaphore的句柄引用。既然它是一个资源类,那么他的使用和操作其他资源类是类似的,在使用前要创建、使用完成后要关闭。

1.Wait() 方法:使信号量减 1。

2.Signal() 方法:使信号量增加 1,如果带参数,则使增加参数所指定的量。

3.Count() 方法:返回当前信号量的值;

以下是两个线程同时使用 两个 TInt 型 :num 和 Tnum 的程序,在这里下载 VC++6 工程文件

#include <e32base.h>
#include <e32cons.h>
#include <E32math.h>

// 定义本地数据
LOCAL_D CConsoleBase* console;
LOCAL_C void ThreadL();
LOCAL_C void NewCsoLC();

LOCAL_C TReal GetRandom();
LOCAL_D TInt err;

const TUint KDefaultHeapSize=0x10000;
//信号量句柄
RSemaphore semaphore;
TInt num;

LOCAL_D RThread T_1,T_2;
LOCAL_D TInt Tnum;

//全局函数,被 E32 调用的主函数,
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
CTrapCleanup* cup=CTrapCleanup::New();
TRAP(err,NewCsoLC());
delete cup;
__UHEAP_MARKEND;
return 0;
}

LOCAL_C void NewCsoLC()
{
__UHEAP_MARK;
_LIT(TITLE,"RThread Demo");
TSize Ts=TSize();
Ts.SetSize(-1,-1);
console=Console::NewL(TITLE,Ts);
CleanupStack::PushL(console);

console->Printf(_L("Press [C] or [D] "));

TInt i=0;
TKeyCode key;
while(i<1000)
{
key=console->Getch();
//按 Esc 键 退出
__ASSERT_ALWAYS(key!=27,User::Panic(_L("End Thread"),key));
console->Printf(_L("[%d:%c] "),key,key);

// 按 C 键 清除屏幕
if (key==99)
{
console->SetTitle(_L("ClearScreen"));
console->ClearScreen();
}

//press 1 User::After 测试
if (key==49)
{
console->SetTitle(_L("User::After Test"));
for(TInt myi=0;myi<=100;myi++)
{
User::After(10000*(100-myi));
console->Printf(_L("showText:%d "),myi);
}
}

//press 2 User::At 测试
if (key==50)
{
console->SetTitle(_L("User::At Test"));
TTime ttm;
ttm.HomeTime();

TDateTime dtm;
dtm=ttm.DateTime();
console->Printf(_L("%d-%d-%d %d:%d:%d.%d "),dtm.Year,dtm.Month(),dtm.Day(),dtm.Hour(),dtm.Minute(),dtm.Second(),dtm.MicroSecond());
TTimeIntervalSeconds itv=3;
ttm+=(itv);
dtm=ttm.DateTime();
console->Printf(_L("%d-%d-%d %d:%d:%d.%d "),dtm.Year,dtm.Month(),dtm.Day(),dtm.Hour(),dtm.Minute(),dtm.Second(),dtm.MicroSecond());

User::At(ttm);
console->Printf(_L("User::At Test "));
}
// 按 B
if (key==98)
{

TInt64 seed = User::TickCount();
//console->Printf(_L("seed=%d "),seed);
//while(true)
TReal64 a=9;
Math::Pow(a,TReal(2),TReal(32));

console->Printf(_L("%f "),a);

console->Printf(_L("%f "),TReal(Math::Random())/a);

/*
for(TInt ib=0;ib<=10;ib++)
{
User::Beep(1000000,1000000);
}
*/
}
// 按 D
if (key==100)
{

TRAPD(err,ThreadL());
}
}

CleanupStack::PopAndDestroy();
__UHEAP_MARKEND;
}

TInt ThreadFunction(TAny* aAny)
{

TInt *increment = reinterpret_cast<TInt*>(aAny);
for(TInt i=0;i<100;i++)
{
//semaphore.Wait();
Tnum=*increment;
num =100+TInt((*increment)*GetRandom());
User::After(TInt(500000*GetRandom()));

if(i>50)
{
T_1.Kill(0);
semaphore.Signal();
}
if(i>70)
{
T_2.Kill(0);
semaphore.Signal();
}

}
//使信号量的值增加
semaphore.Signal();
Tnum=*increment+10;
return 0;

}

 

LOCAL_C void ThreadL()
{

num = 100;

TInt inc1 = 10, inc2 = -10;

TInt err = T_1.Create(_L("T_1"),ThreadFunction,KDefaultStackSize,KDefaultHeapSize,KDefaultHeapSize,&inc1);
CleanupClosePushL(T_1);
User::LeaveIfError(err);

err = T_2.Create(_L("T_2"),ThreadFunction,KDefaultStackSize,KDefaultHeapSize,KDefaultHeapSize,&inc2);
CleanupClosePushL(T_2);
User::LeaveIfError(err);

//创建一个信号量并初始化
semaphore.CreateLocal(0);


T_1.Resume();
console->Printf(T_1.FullName());
console->Printf(_L(" "));

//
User::After(100000);

T_2.Resume();
console->Printf(T_2.FullName());
console->Printf(_L(" "));


while(semaphore.Count()<2)
{
console->Printf(_L("[%d:%d] "),Tnum,num);
User::After(10);

}

console->Printf(_L("[%d:%d] "),Tnum,num);

T_1.Kill(0);
T_2.Kill(0);

T_1.Close();

// 当两个进程都结束了,那么
// 弹出栈顶的两个元素
CleanupStack::PopAndDestroy(2);

console->Printf(_L("Thread Test: "));

}

// 获得一个O-1的随机数
LOCAL_C TReal GetRandom()
{
TReal64 a=0;
Math::Pow(a,TReal(2),TReal(32));
a=TReal(Math::Random())/a;
return a;

}

 

http://www.niftyadmin.cn/n/1353781.html

相关文章

Symbian系统中的异常处理和清理机制

Symbian系统中的异常处理和清理机制一、介绍在Symbian系统中处理异常的方法与传统的标准C中的try,catch机制有很大的不同。Symbian系统提供了一些特殊的清理机制来解决这个问题。系统提供了TRAP/TRAPD宏、CleanupStack类以及一些约定俗成的方法&#xff08;例如Leave函数&#…

Symbian 网络编程之使用Socket API

简介 通过这篇文章我们想为大家带来一些Symbian操作系统的有关sockets API的基本介绍。 本文的读者应该是希望在他们的应用程序中增添socket通信功能的Symbian操作系统的开发者&#xff0c;本文不仅提供了理论介绍&#xff0c;同样给出了可供实践参考的代码范例。 本文包含…

FTP:文件传输协议(指令及响应代码)

文件传输协议&#xff08;FTP&#xff09;使得主机间可以共享文件。 FTP 使用 TCP 生成一个虚拟连接用于控制信息&#xff0c;然后再生成一个单独的 TCP 连接用于数据传输。控制连接使用类似 TELNET 协议在主机间交换命令和消息。 FTP 的主要功能如下&#xff1a; 提供文件的共…

S60 3rd MMP CAPABILITY

S60 3rd MMP CAPABILITY UIQ3 Capabilities&#xff08;Symbian OS9&#xff09;能力&#xff08;Capabilities&#xff09;从Symbian 9开始平台安全性的问题被引入&#xff0c;这意味着&#xff0c;硬件设备只能有限的访问安全的数据和软件。因此在S60第三版和UIQ3的设备上&a…

symbian中得到应用程序的路径

代码1&#xff1a; void GetFullPathName(TDes& aFileName){// Get default drive and pathTParse parse;TFileName appPath;TBuf<5> appDrive;parse.Set(CEikonEnv::Static()->EikAppUi()->Application()->AppFullName(), NULL, NULL);appPath.Copy(parse…

BCB编写DLL终极手册

一. 编写 DLLFile/New/Dll 生成 Dll 的向导&#xff0c;然后可以添加导出函数和导出类导出函数&#xff1a;extern "C" __declspec(dllexport) ExportType FunctionName(Parameter)导出类&#xff1a;class __declspec(dllexport) ExportType ClassName{...}例子&…

wow tbc dz 天赋

19/42/0 http://www.wowar.com/tools/wowar/info/talents/rogue.shtml?1053201250000000000003203050022055100203012510000000000000000000000 41、20、0 http://www.wowar.com/tools/wowar/info/talents/rogue.shtml?30530010504213250105130300520200500000000000000000…

Symbian 各种资源的定义

各种资源的定义一、最基本的定义格式 /* Copyright (c) 2002, Nokia. All rights reserved */NAME HELL  //资源的&#xff29;&#xff24;。在一个项目内保证无重复名称#include <eikon.rh> //必须的一些内部结构和常量的定义 #include <eikon.rsg> …