Gecko 線程分析二

線程分析二   之  nsIThread     nsThread

Gecko是如何使用Thread的。這些天一直覺得gecko中是使用自己的線程機制來完成事件的調用的。否則很難真正搞懂gecko中內部的工作流程。(可是老闆就是不重視,自己想來想去的,按他自己的想法指揮。)沒辦法,只能自己來看gecko線程機制是怎麼回事兒了。

通過從網上查找資料和自己對代碼的查找了解,現在對gecko的線程情況總結整理如下。


首先,Gecko內部的thread基本是使用nsIThread這個interface,通過NS_NewThread來產生。

thread 會有一個job queuethread會一直執行queue裏面的job,如果沒有job時,則是停留在queue內部,此時不會消耗額外的cpu;而由NS_NewThread所產生的thread會由另外一個classnsThreadManager來管理,當系統要停止時,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)


對於以上函數的介紹在geckoidl聲明的註釋中有很好的解釋:

/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時,便會新增一個jobnsThreadqueue裏面,然後sThread便會去執行HelloWorld()這個function,打印出”here is HelloThread”.


下面是幾個注意點:

1HelloThread不一定要繼承RefCounted,只要有AddRefRelease即可。

2、只要調用NS_DispatchToMainThread便會將job指定給MainThread

3Shutdown是一個blockingfunction,當執行sThread->Shutdown時,會等待將thread內部所有的job都執行完纔會離開。

4、不要sThread本身調用自己Shutdown,這樣會造成死鎖。


nsThread 成員函數:


AddRef()

nsISupports


adjustPriority(inlong delta)

nsISupportsPriority


dispatch(innsIRunnable event, in unsigned long flags)

nsIEventTarget


DISPATCH_NORMAL

nsIEventTarget


DISPATCH_SYNC

nsIEventTarget


GetPRThread()

nsThread

[inline]

hasPendingEvents()

nsIThread


Init()

nsThread


InitCurrentThread()

nsThread


isOnCurrentThread()

nsIEventTarget


nsThread()

nsThread


nsThreadShutdownEvent class

nsThread

[friend]

observer

nsIThreadInternal


popEventQueue()

nsIThreadInternal


priority

nsISupportsPriority


PRIORITY_HIGH

nsISupportsPriority


PRIORITY_HIGHEST

nsISupportsPriority


PRIORITY_LOW

nsISupportsPriority


PRIORITY_LOWEST

nsISupportsPriority


PRIORITY_NORMAL

nsISupportsPriority


processNextEvent(inboolean mayWait)

nsIThread


PRThread

nsIThread


pushEventQueue(innsIThreadEventFilter filter)

nsIThreadInternal


QueryInterface(innsIIDRef uuid,[iid_is(uuid), retval] out nsQIResult result)

nsISupports


Release()

nsISupports


sGlobalObserver

nsThread

[static]

shutdown()

nsIThread


ShutdownRequired()

nsThread

[inline]





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章