线程分析二 之 nsIThread nsThread
Gecko是如何使用Thread的。这些天一直觉得gecko中是使用自己的线程机制来完成事件的调用的。否则很难真正搞懂gecko中内部的工作流程。(可是老板就是不重视,自己想来想去的,按他自己的想法指挥。)没办法,只能自己来看gecko线程机制是怎么回事儿了。
通过从网上查找资料和自己对代码的查找了解,现在对gecko的线程情况总结整理如下。
首先,Gecko内部的thread基本是使用nsIThread这个interface,通过NS_NewThread来产生。
thread 会有一個job queue,thread会一直执行queue里面的job,如果沒有job时,则是停留在queue內部,此时不会消耗额外的cpu;而由NS_NewThread所产生的thread会由另外一个class,nsThreadManager来管理,当系统要停止时,nsThreadManager会把它所管理的所有的thread分别调用nsIThread::Shutdown,来将其下的thread停止。
下面是nsIThread的主要函数:
class NS_NO_VTABLE nsIThread : publicnsIEventTarget {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ITHREAD_IID)
/* [noscript] readonly attributePRThread PRThread; */
NS_IMETHOD GetPRThread(PRThread**aPRThread) = 0;
/* void shutdown (); */
NS_IMETHOD Shutdown(void) = 0;
/* boolean hasPendingEvents (); */
NS_IMETHOD HasPendingEvents(bool*_retval) = 0;
/* boolean processNextEvent (inboolean mayWait); */
NS_IMETHOD ProcessNextEvent(boolmayWait, bool *_retval) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIThread, NS_ITHREAD_IID)
对于以上函数的介绍在gecko的idl声明的注释中有很好的解释:
/B2G/gecko/xpcom/threads/nsIThread.idl
下面是nsIThread的继承图和工作的协作图:
下面我们来看一段简单的例子:
nsCOMPtr<nsIThread> sThread;
class HelloThread : public RefCounted {
public:
void HelloWorld() {
printf("here is HelloThread");
}
};
void InititalizeThread() {
NS_NewThread(getter_AddRefs(sThread));
}
void ReleaseThread() {
sThread->Shutdown();
}
void AddJob() {
nsCOMPtr<nsIRunnable> event =NS_NewRunnableMethod(new HelloThread(), &HelloThread::HelloWorld);
sThread->Dispatch(event,NS_DISPATCH_NORMAL);
}
上面是一个简单的helloThread,当使用者调用AddJob时,便会新增一个job到nsThread的queue里面,然后sThread便会去执行HelloWorld()这个function,打印出”here is HelloThread”.
下面是几个注意点:
1、HelloThread不一定要继承RefCounted,只要有AddRef和Release即可。
2、只要调用NS_DispatchToMainThread便会将job指定给MainThread。
3、Shutdown是一个blockingfunction,当执行sThread->Shutdown时,会等待将thread内部所有的job都执行完才会离开。
4、不要sThread本身调用自己Shutdown,这样会造成死锁。
nsThread 成员函数:
AddRef() |
|
|
adjustPriority(inlong delta) |
|
|
dispatch(innsIRunnable event, in unsigned long flags) |
|
|
|
||
|
||
|
||
|
||
Init() |
|
|
|
||
|
||
nsThread() |
|
|
nsThreadShutdownEvent class |
|
|
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
processNextEvent(inboolean mayWait) |
|
|
|
||
pushEventQueue(innsIThreadEventFilter filter) |
|
|
QueryInterface(innsIIDRef uuid,[iid_is(uuid), retval] out nsQIResult result) |
|
|
Release() |
|
|
|
||
shutdown() |
|
|
|