一个线程的CActiveScheduler循环的伪代码:
while(!Finished()) { User::WaitForAnyRequest();//line 1 if(OneOfAOInQueueComplete()) AO->RunL(); else StripSignalHappened(); }
|
当前线程的Request Semaphore增加以后,line 1就会继续执行。
那么如果调用User::WaitForRequest(status)呢? 不会吃掉先回来的信号量,继续等待status对应的信号量。来了就减1,并执行status对应RunL。
当你Cancel一个Request的时候,User::WaitForRequest(status)会吃掉对应的信号量,假设Cancel都会立即返回,这个wait不会消耗太多的时间。
User::RequestComplete(status,KErrNone)会做两件事情,将KErrNone copy到status当中去,将线程的Request Semaphore加1.
最近终于知道在Symbian中使用多线程是多么的困难,因为symbian本身将线程、活动调度器和活动对象组合在了一起使用!
本质上来说,我们所写的代码都是运行在一个RunL里面的! 那么如果你写的线程不想使用活动对象,那么你的线程也无法使用其它很多类了!
线程中的activescheduler一旦启动后,就不会执行runl之外的函数了!
可惜现实中还是需要有多线程的程序,如何更方便的使用线程呢? 理解活动调度器框架和线程中通信吧!
symbian是如何实现线程间的回调的呢? 并且M类的接口函数是在本线程执行的,不是在另外的线程执行的!
我的试验:
在新的thread里面需要了一个CMdaAudioOutputStream(在其他线程创建是不行的,它的内部实现用到了AO),这样我就必须使用ao的一套框架,想用其它机制就不可能了。并且CMdaAudioOutputStream的回调,我原来以为是在其它线程里执行的,其实所有的回调都在我创建的线程里执行的!
我猜测,线程之间的回调可能用到命令模式之类的东西,每个回调方法对应一条命令,服务器执行完之后,将对应的命令发给客户端,客户端是一个AO,在RunL里面根据命令执行对这些回调的调用。
inline void SendReceive(TInt aFunction, const TIpcArgs &aArgs, TRequestStatus &aStatus) const;
|
服务器端也是用ao来实现的。
所以,要想写多线程程序,一定要知道那些类你可以在其他线程创建,在本线程使用;那些类不可以!R类和C类都应该特别注意!T类是肯定没有问题的!
阅读(1167) | 评论(0) | 转发(0) |