`
venus585625
  • 浏览: 253180 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

转载: 《Symbian OS:线程编程》

阅读更多
《Symbian OS:线程编程》
Symbian操作系统中的线程和进程

在Symbian操作系统中,每个进程都有一个或多个线程。线程是执行的基本单位。一个进程的主线程是在进程启动时生成的。
Symbian属于抢占式多任务操作系统,这意味着每个线程都有自己的执行时间,直到系统将CPU使用权给予其他线程。当系统调度时,具有最高优先权的线程将首先获得执行。
进程边界是受内存保护的。所有的用户进程都有自己的内存地址空间,同一进程中的所有线程共享这一空间,用户进程不能直接访问其他进程的地址空间。
每个线程都有它自己的stack和heap,这里heap可以是私有的,也可以被其他线程共享。应用程序框架生成并安装了一个active scheduler,并且为主线程准备了清除栈。如果没有使用框架(如编写exe程序)那就要手动生成这些了:)
Symbian操作系统专为单线程应用优化,因此强烈推荐使用“活动对象”代替多线程。

一、使用单线程的优点
在每个线程都有自己的stack空间时,使用单线程可以减少内存耗费。
在线程间切换上下文要比切换活动对象(通过active scheduler)慢得多。
不需要处理互斥现象,这减少了程序的负担,简化了代码,减少了错误发生的几率。
一些资源只能为主线程所用,因此它们并不是线程安全的,如动态数组。

二、使用多线程的优点
有时为了保证所执行的任务的持续性,如播放声音时,我们可以将其归在一个单独的线程中处理。
将复杂的多线程或长时间运行程序移植到Symbian上,如果不使用多线程处理,可能会比较难也更耗时间。
(题外话:我曾綺将一个棋类程序移植到symbian上,里面复杂的递归运算使我不得不使用多线程,这样的情况下,你是很难将时间有序的分化开来,使用活动对象的)


三、线程的基本使用方法
RThread提供了线程的各项功能。线程是为内核所拥有的对象,RThread对象封装了这些对象的句柄。

1、生成一个新线程
新的线程可以通过构造一个RThread对象,并调用它的Create()函数生成。如:

Code:
1: TInt threadFunction(TAny *aPtr)
2: {
3: // points to iParameter
4: TInt *i = (TInt *)aPtr;
5: ?_
6: }
7:
8: RThread thread;
9: thread.Create(KThreadName, threadFunction, 4096,
10: KMinHeapSize, 256*KMinHeapSize, &iParameter);
11: thread.Resume();2、线程状态
一个线程的最重要的状态为运行、准备、等待和暂停。在生成后,线程首先处于暂停状态,你可以调用Resume()函数来启动它的运行。一个线程也可以通过调用Suspend()来进入中断状态。

线程一般通过Kill(TInt aReason)来结束,Terminate()与其相似。如果一个进程的主线程结束,则该进程与所属所有线程都将结束。
一种非正常关闭线程的方式就是调用Panic(const TDesC& aCategory, TInt aReason)来中断执行。
如何获得中断线程的信息呢,我们可通过ExitType(),ExitReason()以及ExitCategory()方法来获得。

线程可以在中断时发出请求,我们通过调用异步方法Logon()来完成此任务。返回值在aStatus中。LogonCancel()可以取消前次请求。
void Logon(TRequestStatus& aStatus) const;
TInt LogonCancel(TRequestStatus& aStatus) const;

我们可以通过SetProtected(ETrue)方法将线程保护起来,也可以通过SetProtected(EFalse)来取消保护。在保护时,另一个线程是无法中断、结束、异常中断或设置该线程的优先级的。Protected()方法可以返回该线程的保护状态。

3、访问线程及进程
我们可以通过构造一个RThread对象来访问当前线程。Id()方法可以返回改线程的ID。
拥有此线程的进程可以通过访问RThread的Process(RProcess& aProcess)方法来获得。这里传入的参数应该是一个RProcess对象。
其他线程可以通过Open()方法来访问。我们通过传递TThreadId、线程名称或TFindThread对象来打开线程。
TInt Open(const TDesC& aFullName, TOwnerType aType=EOwnerProcess);
TInt Open(TThreadId aID, TOwnerType aType=EOwnerProcess);
TInt Open(const TFindThread& aFind, TOwnerType aType=EOwnerProcess);


Code:
1: // * as a wildcard for the name search
2: _LIT(KFindAll, “*”);
3: // default RThread object, has a handle of the current thread
4: RThread thread;
5: TFullName fullName;
6: TFindThread finder(KFindAll);
7:
8: while (finder.Next(fullName) == KErrNone)
9: {
10: // on success, variable ‘thread’ will contain a handle of
11: // a thread found by finder
12: thread.Open(finder);
13:
14: // get thread’s memory information
15: TInt heapSize, stackSize;
16: thread.GetRamSizes(heapSize, stackSize);
17:
18: // show fullName, heapSize and stackSize
19: ...
20: }4、线程优先级
线程可以被赋予一个绝对或相对的优先级。绝对优先级定义了这个线程的总体优先级,不需要考虑其拥有者进程的优先级了。而赋予相对优先级时则将此线称定义为拥有者进程的优先级加上该相对优先级后的结果。

下面粗体标示的优先级值可以由用户代码设置:

Code:
enum TProcessPriority
{
   EPriorityLow=150,
   EPriorityBackground=250,
   EPriorityForeground=350,
   EPriorityHigh=450,
   EPriorityWindowServer=650,
   EPriorityFileServer=750,
   EPriorityRealTimeServer=850,
   EPrioritySupervisor=950
};

enum TThreadPriority
{
EPriorityNull=(-30),
EPriorityMuchLess=(-20),
EPriorityLess=(-10),
EPriorityNormal=0,
EPriorityMore=10,
EPriorityMuchMore=20,
EPriorityRealTime=30,
EPriorityAbsoluteVeryLow=100,
EPriorityAbsoluteLow=200,
EPriorityAbsoluteBackground=300,
EPriorityAbsoluteForeground=400,
EPriorityAbsoluteHigh=500
};上面枚举出来的值中绝对优先级值为:
EPriorityAbsoluteVeryLow, EPriorityAbsoluteLow, EPriorityAbsoluteBackground, EPriorityAbsoluteForeground, EPriorityAbsoluteHigh.
相对优先级值为:
EPriorityMuchLess, EPriorityLess, EPriorityNormal, EPriorityMore, EPriorityMuchMore.
EPriorityNull是一个特殊值,它定义了最低的级别,Kernel idel thread使用的就是它*_*

EPriorityRealTime定义了除核心服务线程优先级外最高的总体优先级。
RThread中的Priority()方法返回了一个线程的优先级(按以上描述值)。我们也可以通过SetPriority(TThreadPrioriy aPriority)方法来修改优先级。
ProcessPriority()方法返回了拥有该线程之进程的优先级(按TProcessPriority描述值)。我们也可以通过SetProcessPriority(TProcessPriority)方法来修改该进程的优先级。

5、异常处理
每个线程都有自己的异常处理模块。当线程发生异常时会调用异常处理模块。异常处理模块的訽型为:
typedef void TExceptionHandler(TExcType);

RThread包含了下列异常处理相关的方法:
TExceptionHandler* ExceptionHandler()
返回该线程当前异常处理模块的地址。

TInt SetExceptionHandler(TExceptionHandler* aHandler, TUint32 aMask);
定义了该线程新的异常处理模块的地址,以及它所处理异常的类别。

void ModifyExceptionMask(TUint32 aClearMask, TUint32 aSetMask)
修改异常处理模块所定之异常类别,aClearMask参数定义了不再为异常处理模块所处理的类别,而aSetMask则定义了新的处理类别。

TInt RaiseException(TExcType aType);
引发线程上指定类型的异常,这时异常处理模块将被启动执行(发生在调用之后)。

TBool IsExceptionHandled(TExcType aType);
检查线程的异常处理模块是否捕捉到aType类型的异常。


(1)异常类别及类型
异常类型是一组针对单个异常的类型识别,主要用在异常发生时。
异常类别则代表一组异常形式。

异常类别的一个集是由一个或多个异常类别通过OR形式组合成的,如KExceptionInteger|KExceptionDebug,这些值用来设置及修改异常处理模块所处理的类别。

下面列示了所有的类型及类别。
异常类别 异常类型
KExceptionInterrupt ->EExcGeneral, EExcUserInterrupt
KExceptionInteger ->EExcIntegerDivideByZero, EExcIntegerOverflow
KExceptionDebug->EExcSingleStep, EExcBreakPoint
KExceptionFault ->EExcBoundsCheck, EExcInvalidOpCode, EExcDoubleFault, EExcStackFault, EExcAccessViolation, EExcPrivInstruction, EExcAlignment, EExcPageFault
KExceptionFpe ->EExcFloatDenormal, EExcFloatDivideByZero, EExcFloatIndexactResult, EExcFloatInvalidOperation, EExcFloatOverflow, EExcFloatStackCheck, EExcFloatUnderflow
KExceptionAbort ->EExcAbort
KExceptionKill->EExcKill
6、其他线程函数
TInt Rename(const TDesC& aName)
为线程定义个新名字。

void RequestComplete(TRequestStatus*& aStatus, TInt aReason)
通知线程与一个异步请求绑定的请求状态对象aStatus已綺完成。sStatus完成代码将负责设置aReason及发出线程请求信号的通知。

TInt RequestCount()
返回线程请求信号的数目。如果是负值则表示该线程正在等待至少一个异常请求的完成。

void HandleCount(TInt& aProcessHandleCount, TInt& aThreadHandleCount)
得到线程中及拥有该线程的进程中处理模块的数目。

RHeap* Heap()
返回一个指向改线程堆的指针。

TInt GetRamSizes(TInt& aHeapSize, TInt& aStackSize)
得到该线程中堆和栈的大小。

TInt GetCpuTime(TTimeIntervalMicroSeconds& aCpuTime)
得到改线程所分配到的CPU时间

void Context(TDes8& aDes)
得到该线程( sleeping状态)所注册的上下文环境。

四、线程内部的通信
1)共享内存
在线程间交换信息最直接的方法就是使用共享内存。线程入口函数中有一个参数TAny* aPtr,这个指针可以用于任何目的。通常可以用它来传递一个负责线程间共享信息的数据结构或类实例。因为同一进程中的线程是共享内存地址空间的,因此这里指针所指向的数据可以被两个线程所共享,注意访问该数据时必须是同步形式。
另外这里的指针参数可以使用SetInitialParameter(TAny* aPtr)方法来改变,但这时线程应处于suspend状态。

2)Client/Server API
Symbian操作系统提供了一组基于server/session的API,允许一个线程扮演server的角色,向其他线程或进程提供服务。这里API也提供处理一组方法处理信息的传递,异步以数据传输。

3)进程内数据传输
如果两个线程分属不同的进程,则他们无法直接管理需要通信的数据,因为他们没有共享的数据区。这里可以使用RThread提供的ReadL()方法及WriteL()方法,我们可以用来在当前线程和由RThread提供的另一个线程间的地址空间拷贝8/16位的数据。这里当前线程和另一个线程可以归属同一个进程也可分属不同进程。

数据的传输是通过拷贝数据来完成的,RThread提供了方法返回在它地址空间内一个descriptor的长度及最大允许长度。

a>读取另个线程所提供的descriptor
void ReadL(const TAny* aPtr,TDes8& aDes,TInt anOffset) const;
void ReadL(const TAny* aPtr,TDes16 &aDes,TInt anOffset) const;

这里ReadL()方法从另一个线程的descriptor(由aPtr所指)中拷贝一组数据,传递到当前线程的descriptor(由aDes所指)。
aPtr指针必须指向一个在RThread句柄所指线程的地址空间中有效的descriptor。

从源descriptor中的内容是从anOffset位置那里开始拷贝到目的descriptor(aDes)的。

b>向另个线程写入descriptor
void WriteL(const TAny* aPtr, const TDesC8& aDes, TInt anOffset) const;
void WriteL(const TAny* aPtr, const TDesC16& aDes, TInt anOffset) const;

用这个方法将当前线程descritor(aDes)所提供的数据都拷贝在另一个线程(aPtr所指)的descriptor中。这里anOffset参数设定了目标descriptor的初始化拷贝位置。

aPtr为线程地址空间内有效的可修改descriptor。

如果拷贝进去的数据长度超过目标descriptor的最大长度,则函数会发生异常。

c>Descriptor帮助函数
TInt GetDesLength(const TAny* aPtr) const;
TInt GetDesMaxLength(const TAny* aPtr) const;
这里RThread的GetDesLength()方法可以返回aPtr所指向的descriptor长度。这里descriptor必须为RThread句柄所指定的线程的地址空间中。
RThread的GetMaxDesLength()方法返回aPtr所指向descriptor的最大长度。descriptor也应在RThread句柄所指的线程地址空间中。

建议在ReadL()和WriteL()等方法前使用这些函数。

4)线程局部存储(TLS)
Symbian操作系统是不允许在DLL中出现可写静态变量的。然而每个DLL中每个线程都会分配一个32位字符空间。这个字符用来存放一个指向数据结构或类示例的指针。分配和释放这些资源可在例如DLL的入口函数E32Dll中处理。

另一个使用线程局部存储的示例为保存指向类示例的指针,这样静态回调函数可以访问与线程相联系的该对象。当我们处理自定义异常处理模块时是很有用的。

Dll::SetTls(TAny *aPtr)函数负责设置线程局部存储的指针。
Dll::Tls()函数负责返回一个指向线程局部存储的指针。取得后该指针所指定数据可以正常使用。

5) User-Interrupt Exception
如3.5“Exception Handling”所述,线程可以引发其他线程的异常。有一种异常类型是专为用户所保留的,那就是EExcUserInterrupt,可以通过指定异常类型KExceptionUserInterrupt来处理。其他要传递的信息应该通过共享内存来处理。这是在最段时间内向其他线程传递信息的方式,当异常发生时调用RaiseException()函数可切换到另个线程的异常处理模块。
6) Publish & Subsribe
Publish & Subscrible是一个进程间的通信机制(在SymbianOS v8.0a和Series 60 Platform 2nd Editon, Feature Pack2中有所介绍),可以查看相关的文挡。

这个机制包括了三个基本方面:properties, publishers, 和subscribers.Properties是由一个标准SymbianOS UID所定义的全局唯一变量,它定义了属性类别,而另一个整数定义了property sub-key。
Publishers是负责更新属性的线程。Subscribers是负责监听属性变化的线程。

7) 消息队列
消息队列是另一个进程间通信的机制(在SymbianOS v8.0a和Series 60 Platform 2nd Editon, Feature Pack2中有所介绍)。
消息队列用来向队列发送消息,而无需获得接收者的状态标识信息。任何进程(都在同一队列中的)或任何同一进程中的线程(在局部队列中)都可以读取这些信息。

五、同步
1)目的
如果多个线程在没有保护机制的情况下使用同一资源,就会出现一些问题。如,线程A更新了部分descriptor,而线程B接手后又重写了内容。回到线程A后,又开始更新内容。这样descriptor的内容就在A与B中来回修改了。

为了防止这类情况的发生,你需要使用非抢占式client/server机制或同步对象来处理。同步对象(mutex, semaphore, critical section)都是核心对象,可以通过句柄来访问。他们会限制或直接锁住对多线程们所要访问的资源,这种资源形式被称为共享资源。
在任何时刻只能有一个线程对共享资源进行写操作,每个要访问资源的线程都应使用同步机制来管理资源。
同步操作一般有如下步骤:
1. Call Wait() of the synchronization object reserved for this resource.
2. Access the shared resource.
3. Call Signal() of the synchronization object reserved for this resource.

注意,当kill线程时要小心点。因为如果线程使用已綺注销的对象,不同的同步对象其处理方式是不同的。因此,忽略使用同步类型而kill一个已綺更新过部分资源的线程是会引发问题的。

2)使用Semaphores(信号)
Semaphores可以管理共享资源的同步化访问。这里semaphore的句柄可通过RSemaphore类获得。
Semaphore限制了同一时刻访问共享资源的数目。semaphore计数的初始化工作可以放在构造函数中进行。
Semaphore可以是全局的也可以是局部的,全局的semaphore有自己的名称,可以被其他进程搜索并使用。而局部的semaphore没有名称,只能在同一进程间的线程中使用。
调用semaphore的Wait()方法将减少semaphore计数,而如果计数为负的话,调用线程就会进入等待状态。
调用semaphore的Signal()方法将增加semaphore计数,如果增长之前为负数,则等待信号的第一个线程将设定为准备运行状态。

调用semaphore的Signal(TInt aCount)和调用n次Signal()效果是一样的。
当线程死亡时,只有该线程正等待该信号时,信号才能被通知。因为信号在下面这样的情况也是可以执行的:在一个线程中调用Wait(),在另一个线程中调用Signal(),这样的信号无法在使用它的线程死亡时被通知。这样只会导致信号计数减低。

3)使用互斥(Mutex)
互斥主要使用在同步下独占访问共享资源。它的句柄可以通过RMutex类来获得。
和信号一样,互斥可以是全局也可以是局部的。唯一的不同在于其计数初始化时总为1。Mutex因此只允许最多一个访问共享资源。
如果一个线程已綺为mutex调用Wait(),但没有Signal(),则线程死亡时该互斥将被通知。

4)使用临界区(Critical Sections)
Critical Sections可用来在一单独进程中独占访问共享资源。Critical Sections句柄可以通过RCriticalSection类来获得。
Critical Sections只能用在同一进程的线程间,通常它用来管理某段代码的访问,每次只能有一个线程来访问。
同一线程中,在调用Wait()前调用Signale()将会引发线程的异常。但不会出现在其他类型的同步对象中。
线程的中断是不会影响critical sections的状态的,因此使用critical sections的线程将不会被其他线程杀死,除非不在critical sections中。当不在需要时,线程的死亡是不会有癬,很安全的。

5)同步实例

Code:
1: class CMessageBuffer
2: {
3: public:
4: CMessageBuffer();
5: void AddMessage(const TDes &aMsg);
6: void GetMessages(TDes &aMsgs);
7:
8: public:
9: RMutex iMutex;
10: TDes iMsgs;
11: };
12:
13: CMessageBuffer::CMessageBuffer()
14: {
15: iMutex.CreateLocal();
16: }
17:
18: void CMessageBuffer::AddMessage(const TDes &aMsg)
19: {
20: iMutex.Wait();
21: iMsgs.Append(aMsg);
22: iMutex.Signal();
23: }
24:
25: void CMessageBuffer::GetMessages(TDes &aMsgs)
26: {
27: iMutex.Wait();
28: aMsg.Copy(iMsgs);
29: iMsgs.Zero();
30: iMutex.Signal();
31: }
32:
33: static void CMyClass::threadFunction(TAny *aPtr)
34: {
35: CMessageBuffer *msgBuffer = (CMessageBuffer *)TAny;
36: TInt count = 0;
37: TBuf<40> msg;
38:
39: while (TRUE)
40: {
41: msg.Format(“ID: %d, count: %d\n”, RThread().Id(), count++);
42: msgBuffer->AddMessage(msg);
43: User::After(1000 * 1000);
44: }
45: }在上面所述中,CMessageBuffer是一个半成品类,它允许用户增加消息到buffer中,也允许获得所有消息。
线程函数CMyClass::threadFunction负责向CMessageBuffer共享对象添加信息,这里内存分配和错误检查并没有列出,需要读者自己完成。
假设有多个线程要共享CMessageBuffer对象实例,则在实际访问buffer时必须要同步来处理。我们也可在线程函数中完成,但在CMessageBuffer中完成同步将使得该类成为线程安全级,同样它也可以被用在单个线程中了。

六、总结
  很多情况下都需要多线程的,当使用多线程时,同步及互斥排他也要考虑在内,以便保证线程通信的安全性。如果线程使用共享资源,我们应该使用某种同步机制来避免异常的发生,Semaphores, critical sections,和mutexes都提供了基本的解决方案。此外,如果使用活动对象或清除机制,我们还需要手工设置active scheduler和清除栈。总的来说,线程编程不是这么容易的,因为这类编程需要全面理解框架、多任务和线程安全机制。
分享到:
评论

相关推荐

    Symbian OS:线程编程中文版

    《Symbian OS:线程编程中文版》是针对Symbian操作系统进行深入探讨的一份技术文档,尤其聚焦于线程编程这一核心概念。Symbian OS曾是智能手机领域广泛使用的实时操作系统,尤其是在诺基亚等早期智能手机中占据主导...

    Symbian 开发三步曲:Symbian OS C++ For Mobile Phones Ⅰ Ⅱ Ⅲ

    书中详细介绍了Symbian OS的基础架构,包括其微内核设计、进程与线程管理、内存管理和异常处理机制。此外,还详细讲解了如何编写高效、安全的C++代码,以及如何进行设备驱动和系统服务的开发。对于初次接触Symbian ...

    Symbian OS:线程编程

    通过对上述内容的学习,开发者可以更好地掌握Symbian OS线程编程的核心技术,并将其应用于实际项目中。随着技术的发展,虽然Symbian OS已经不再是主流的移动操作系统,但它在多线程处理方面的设计理念和技术仍然值得...

    《Symbian OS C++ 高效编程》 源码

    3. **线程与并发**:Symbian OS支持多线程编程,源码可能包含多线程同步、互斥锁、信号量等概念的实例,这对于构建高效的并发应用程序至关重要。 4. **事件驱动编程**:Symbian OS采用事件驱动模型,通过消息队列和...

    《Symbian OS C++ 手机应用开发》源码(1-2卷)

    1. **线程与并发**:Symbian OS支持多线程编程,开发者可以通过TThread类创建和管理线程。源码中可能会包含线程同步和通信的示例,如信号量、互斥锁和事件对象的使用。 2. **内存管理**:Symbian OS有自己的内存...

    symbian os c++ mobile v3 配套源码code

    1. **线程与并发**:Symbian OS 强调多线程编程,支持并发执行任务。开发者需要理解如何创建、管理和同步线程,以实现高效的并发处理。 2. **事件驱动模型**:Symbian OS 使用事件驱动模型,通过消息队列和事件循环...

    Symbian OS C++编程诀窍源代码.rar

    3. **线程与同步**:Symbian OS中的多线程编程非常重要,源码会演示如何创建和管理线程,以及如何进行线程间的同步,以避免数据竞争问题。 4. **资源管理**:学习如何有效地管理文件、内存、网络连接等资源,这是...

    Symbian OS Explained Effective C++ Programming for Smartphones

    3. **线程与同步**:Symbian OS支持多线程编程,讲解如何创建和管理线程,以及如何实现线程间的同步和通信,以确保程序的正确性和性能。 4. **错误处理**:Symbian OS独特的错误处理机制,如使用异常处理和返回码,...

    最常见的手机操作系统Symbian OS

    4. **软件开发**:Symbian OS支持C++编程语言,提供了Symbian C++ SDK,使得开发者能够创建高效、本地化的应用程序。 **二、Symbian OS的主要特性** 1. **多任务处理**:Symbian OS允许用户同时运行多个应用程序,...

    Symbian OS 精要

    2. **线程管理**:Symbian OS强调多线程编程,开发者需要理解和熟练运用线程同步、互斥锁和信号量等概念,以确保程序的并发执行和资源安全。 3. **内存管理**:Symbian OS有独特的内存管理机制,如自动对象计数和...

    Symbian OS C++ for Mobile Phones Volume 3

    3. **线程与并发**:Symbian OS支持多线程编程,这对于处理多任务和实时响应的移动应用非常重要。书中会介绍如何创建和管理线程,以及如何处理同步和互斥问题。 4. **事件驱动编程**:Symbian OS采用事件驱动模型,...

    SYMBIAN OS C++ 高效编程.rar

    4. **线程与并发**:Symbian OS支持多线程编程,开发者需要掌握如何创建和管理线程,以及如何在多线程环境中正确实现同步和互斥,以避免竞态条件和死锁。 5. **图形用户界面(GUI)编程**:Symbian提供了一系列API...

    Symbian OS C++ for Mobile Phones, Volume 1

    3. **线程和并发编程**:Symbian OS支持多线程编程,理解如何创建和管理线程,以及同步原语(如REvent和RMutex)的使用至关重要。 4. **图形用户界面(GUI)**:Symbian OS提供了Eikonyan和E32UI框架来构建GUI,...

    Symbian OS 架构介绍

    #### 设计模式与组件化:Symbian OS的编程哲学 Symbian OS的设计遵循了面向对象的设计原则,采用了多种设计模式,如工厂模式、单例模式、观察者模式等,以实现代码的重用和模块化。此外,其C++组件化的编程模型允许...

    Symbian OS 项C++手机开发第三版(英文)PDF版

    3. **Symbian编程模型**:Symbian OS采用事件驱动模型,开发者需要理解线程、信号量、消息队列等概念,以实现高效并行处理。 4. **EPOC文件系统**:Symbian OS使用独特的EPOC文件系统,书中会介绍其特性和与传统...

    symbian os c++编程诀窍 随书源码

    4. **线程和同步**:Symbian OS支持多线程编程,但需要特别注意线程安全和同步机制,例如使用`CSyncLock`、`CriticalSection`和`Mutex`等来防止数据竞争。 5. **事件驱动编程**:Symbian的事件驱动模型基于消息循环...

    Symbian OS C++手机应用开发(第3卷)源码

    《Symbian OS C++手机应用开发》(第3卷)是针对Symbian操作系统进行C++编程的一本专业书籍,其源码部分是学习和理解Symbian平台开发的关键资源。Symbian OS曾是智能手机领域的一个主流操作系统,尤其在诺基亚等设备上...

    Symbian OS课件(4)

    7. **线程与同步**:Symbian OS支持多线程编程,理解和掌握如何创建和管理线程,以及如何使用信号量、互斥锁等同步原语防止数据竞争,是开发高效、安全的Symbian应用的基础。 8. **文件I/O**:Symbian OS提供了文件...

    多线程编程中英文对照.rar

    4. **Symbian_OS_Threads_Programming_v1_0_en.pdf**:这是一份英文版的Symbian OS线程编程手册,可能详细讲解了线程的生命周期、调度策略、线程间通信、同步机制(如信号量、互斥锁)以及如何避免线程安全问题。...

Global site tag (gtag.js) - Google Analytics