Gecko 線程分析一

線程管理及主要線程

作爲一個瀏覽器內核,Gecko所要完成的任務是非常繁雜的,其主要任務就是根據用戶提供的資源地址(網址或本地文件路徑),通過http協議從Web服務器中取得頁面文檔,然後解析其內容,最後根據一定的約定在瀏覽器指定區域中顯示出頁面,其中往往涉及網絡編程及圖形界面編程,而大家通常都知道的是網絡編程中的連接、讀取數據等往往需要考慮到服務器端的情況,一般採用異步方式來確保有效處理服務端返回的數據包括連接不成功、錯誤處理等;而圖形界面的處理往往需要採用一個主消息循環及回調函數的方式來處理用戶的動作,爲了給用戶提供平滑的操作而又兼顧後臺服務器的不確定性,一個可行的瀏覽器內核必須充分利用多線程來協調處理複雜的應用場景,只有這樣才能高效的完成其所要完成的任務,初步瞭解Gecko內核的線程模型及相關線程管理的知識,對了解Gecko是非常有幫助的,下面初步瞭解Gecko是如何進行線程管理及其主要線程實現。

Gecko線程模型

爲了統一接口編程,Gecko將其線程模型按照組件的方式來處理,定義的接口主要有nsIRunnablensIEventTargetnsIThreadnsIThreadManagernsIThreadPool,其中nsIThreadManagernsThreadManager來實現(nsI開頭的一般爲接口一般有ns開頭的來實現),它主要用於來管理所有的nsThread,包括創建nsThread實例,並通過維護一些系統原生線程的屬性可以判斷同一段代碼是在什麼線程的上下文中調用,從而可作出不同的處理,如GetIsMainThread可以判定當前執行線程是否爲主線程,這一點在Gecko中應該得到了充分的應用,同時nsThreadManager的實例屬於單例模式,在第一次啓用XPCOM組件時由NS_InitXPCOM3實例化出來,以供以後管理nsThread(位置gecko/xpcom/threads/nsThread.cpp)使用。

gecko的線程管理位於:gecko/xpcom/threads中:


nsIRunnable:


這個接口是所有events/runnable對象的基類。(events/runnable在線程中調度)

具體的事件調度情況在nsRunnable中體現。在此就不多贅述了,之後會進行詳細分析。

nsThread的類圖:



nsThread代表一個普通的線程。

在其構造函數中會初始化它並啓動原生線程,它同時增加了EventQueueThreadObserver的概念

函數入口爲nsThread::ThreadFunc

在線程的整個週期中也即nsThread::ThreadFunc中不斷的處理外部線程或本身向其EventQueueDispatch來的Event,同時每處理一個Event之前都會檢查其是否存在Observer,如存在則先讓Observer調用其OnProcessNextEvent來處理該Event,然後調用Event本身提供的run方法,這樣增加了nsThread處理Event的靈活性

nsThread統一由nsThreadManager來創建,通過調用其Shutdown方法來結束該線程;並提供了一組外部接口來進行線程管理操作

如:
NS_NewThread
NS_GetMainThreadNS_DispatchToMainThreadNS_ProcessNextEvent等以供不同線程調用,同時保證線程安全(文件位置:gecko/xpcom/glue/nsThreadUtils.cpp

       nsThreadPool代表一組線程(即線程池),當外部向其Dispatch一個Event時它先會向其中的EventQueue添加該Event,然後它會根據設置的參數來決定是否分配一個nsThread來處理該Event,一旦創建了一些nsThread則將其維護在mThreads隊列中,同時向該nsThreadDispatch這個nsThreadPool實例以讓該nsThread去執行該nsThreadPoolrun方法,這樣可保證線程池中的每個nsThread的執行體都是nsThreadPool中的run方法,在其run方法中會根據是否空閒等條件自動ShutDown一些暫時不用的nsThread,以達到線程池的目的,即當任務事件Event繁多的時候多開啓一些線程來處理,一旦任務完成則釋放大部分空閒線程,保持一小部分線程以等待新任務的分配及提交;nsThreadPool在異步讀取網絡流數據的時候會經常用到。


Gecko主要線程

MainThreadGecko的主線程,也即進程啓動時的執行序列,它主要處理圖形界面的消息循環以及其他線程向它Dispatch過來的Event,這樣可以有機的結合圖形界面的處理及網絡數據的讀取、解析、渲染等。MainThread線程充分利用了Gecko線程模型特點,既能處理原生的窗口消息,又可及時處理其它線程通知給它的Event,其執行主體往往是Gecko的核心,據初步統計其執行時間往往佔整個程序執行時間的90%以上,其效率的高低直接決定了是否會讓用戶產生阻塞停頓的感覺。其主要實現邏輯是在啓動XPCOM當中會在nsThreadManager初始化時自動產生一個nsThread實例mMainThread,它代表進程啓動時的執行序列,待該執行序列完成其他基本準備後,在nsBaseAppShell::Init中將其Observer設置爲nsBaseAppShell實例本身

先分析到這,待續。。


參考文獻:

https://developer.mozilla.org/en/docs/The_Thread_Manager

https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Threads

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