線程分析二 之 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() |
|
|
|