全部博文(237)
分类:
2009-11-26 13:36:22
一、Symbian系统的线程
symbian系统的线程是建立在Symbian微内核线程的基础上,用于支持用户模式多线程应用
的一种机制。DThread代表了Symbian的系统线程。对于用户模式来说,Symbian开发环境
提供了RThread类来进行常规的线程操作。(RThread是由RHandleBase类派生出来的)
每个Symbian系统的线程对象都包含了一个微内核的线程对象,并且该线程是由内核直接进行
调度的。每个Symbian系统的线程都有两个堆栈,一个是给用户模式线程使用,另一个是给
微内核线程使用的。除此之外,每个Symbian系统的线程还有如下特点:
(1)提供了一系列的不同执行效率的可执行函数,用于用户模式线程调用内核的各种功能
(2)一个异常(Exception)处理函数
(3)一个陷入(Trap)处理函数
(4)一个退出(Exit)函数
(5)活动调度器(Active Scheduler)
(6)一个指向创建当前线程的进程的指针(有点绕口,多读几次就习惯了)
(7)当前线程本身的堆
Symbian线程的状态:
以下的10种状态又称为M状态,是Symbian系统中线程的全部状态:
(1)ECreated: 线程的初始状态
(2)EDead: 线程的最终状态
(3)EReady: 线程准备运行状态,可以立刻开始运行了
(没有被任何Symbian的同步对象阻塞,如semaphore,mutex等)
注意:
对于微内核而言,一个被同步对象阻塞或者挂起的线程(例如fast semaphore)
也有进入这种状态的可能
(4)EWaitSemaphore: 阻塞等候系统的semaphore对象
(5)EWaitSemaphoreSuspended: 另一个线程在当前线程被系统的semaphore阻塞后,明确的要求挂起当前的线程。
(原文:another thread has explicitly suspended this thread after it blocked on a SOS semaphore. )
(6)EWaitMutex: 阻塞等候系统的mutex对象.
(7)EWaitMutexSuspended: 另一个线程在当前线程被系统的mutex阻塞后,明确的要求挂起当前的线程。
(原文:another thread has explicitly suspended this thread after it blocked on a SOS mutex. )
(8)EWaitMutexPending: 从EWaitMutex状态中苏醒过来
(9)EWaitCondVar: 阻塞等待系统的条件变量(conditional variable)
(10)EWaitCondVarSuspended: 另一个线程在当前线程被系统的条件变量阻塞后,明确的要求挂起当前的线程。
每个线程都有一个iWaitObj对象指针,它指向当前正在阻塞等待的同步对象(如mutex,semaphore,
或条件变量)
注意:
由于mutex对象紧密相关的状态有三种:
EWaitMutex,EWaitMutexSuspended和EWaitMutexPending。
因此,对于执行用mutex对象保护的同一块代码段的两个线程来说,当它们被内核调度的时候,
与同样的被semaphore对象保护的代码段相比,会有完全不同的动作。
假定有如下代码:
void ThreadSafeFunction()
{
TInt index = 0;
for ( ;index < KLoopCount; index++)
{
mutex.Wait();
//access some global/common data here
mutex.Signal();
}
}
我们假设有两个线程(我们叫它们A和B),在同一时刻执行了同样的函数。
如果A首先进入了这个函数,在执行的时候会通过执行mutex.Wait()函数
请求当前的mutex对象,它在申请mutex完毕的时候被内核调度程序抢占了。
这样B就占有了CPU,在B进入到同样的函数的时候,B请求mutex对象的结果
是EWaitMutex状态,当前mutex被A首先得到了。于是B就会处于阻塞状态,
一段时间以后(这段时间非常短),当内核的调度器调度到A,A开始重新
执行,A会通过mutex.Signal()释放其申请的mutex。注意:这并不代表B会
阻塞A来继续执行。该Signal操作会把当前B的状态设置成EWaitMutexPending。
A会继续执行,直到A的cpu时间片超时(默认情况下是20微秒),或者A退出,
或者A由于别的原因再次阻塞或挂起。尽管即使A已经释放掉了B阻塞等待的mutex,
B仍然不会重新运行。
如果在上述函数中使用semaphore而不是mutex,那么动作就会完全不同了,
当A释放了当前semaphore,那么处于EWaitSemaphore状态的B将立刻开始
继续执行。这样的话,A由于再次申请semaphore不成功,而被阻塞。
呵呵,这是由于semaphore只有两个状态(EWaitSemaphore,EWaitSemaphoreSuspended)
导致的。