在Chrome的多進程模型裡面,有一個主進程和多個輔助進程。主進程Browser負責處理chrome的大部分工作,並且負責建立和銷毀其他輔助進程,輔助進程稱為Renderer進程,他們主要負責頁面的顯示工作。每個Renderer進程對應一個或者多個頁面或者說網站。下面是Chrome首頁上的一張進程模型圖。很形象的展示了Chrome的多進程模型。
一般的,WINDOWS下面的應用程式以單進程的方式工作,為什麼Chrome要採用多進程方式。在官方文檔裡面解釋的很清楚:Google們認為如今的瀏覽器有點類似於早期的單使用者多任務作業系統,一個外掛程式產生的異常就能導致整個瀏覽器以及它所開啟的多有網頁標籤的崩潰。因此,Google決定讓不同的頁面運行在不同的進程上,這樣某個頁面產生的異常只會導致這個頁面的崩潰,但是不會影響到其他頁面和整個瀏覽器的工作。
通過這個圖我們可以很清楚的看到Browser進程又包括了多個線程,至少有一個MainThread和一個I/O Thread 。
建立主線程的代碼如下:
void BrowserMainParts::MainMessageLoopStart() {
PreMainMessageLoopStart();
main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI));
// TODO(viettrungluu): should these really go before setting the thread name?
system_monitor_.reset(new SystemMonitor);
hi_res_timer_manager_.reset(new HighResolutionTimerManager);
network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
InitializeMainThread();
PostMainMessageLoopStart();
}
分析一下這段代碼。首先建立一個MessageLoop的對象,MessageLoop在建構函式中會把指向自己的指標保持在當前線程的TLS中,如下:
lazy_tls_ptr.Pointer()->Set(this);
以後很多地方會用到這個東西,比如很多IO線程的回呼函數調用的時候會擷取這個指標來判斷自己是否運行在IO線程上,如果不是則會觸發異常,建構函式同時設定了線程的類型值。
接下來做的工作是初始化系統監視對象和network_change_notifier_對象。
接著開始初始化MainThread,這裡調用的是 main_thread_.reset(new BrowserThread(BrowserThread::UI, MessageLoop::current())),建立了一個對應當前住線程的對象,到這裡所有的工作就結束了,而主線程的訊息迴圈要到主視窗建立之後才啟動,調用的是RunUIMessageLoop(browser_process.get());
同時,在BrowserProcess中還建立了RendererProcessHost對象,每個RendererProcessHost對應一個RendererProcess,RendererProcess中還包含多個RendererViewHost對象,每個RendererViewHost對應RendererProcess中的一個RenderView對象,RenderView對應這使用者可見的頁面標籤。RendererProcess主要的責任就是使用web渲染引擎來顯示html頁面,目前Google使用的webkit和v8雙重引擎來渲染頁面,從28開始,將會換成Blink引擎。的關係可以看出來一個RendererProcess同時管理著多個頁面的渲染工作。RendererProcess本身沒有網路通訊功能,如果RendererProcess的引擎需要資料,必須通過處理序間通訊從BrowserProcess那裡擷取。而主進程中的RendererProcessHost就是用來同一個確定的RendererProcess建立聯絡的,每個RendererProcessHost同RendererProcess之間通過一個Channel建立了固定的聯絡,一直維持到RendererProcess被銷毀。Channel在底層使用的是具名管道的機制,以後再專門分析這個處理序間通訊機制。
BrowserProcess還有一個IO線程。負責所有的網路通訊和處理序間通訊。每個RendererProcess產生的資料請求在主進程排序之後會交給IO進程,IO進程中包含一個ResourceDispatcherHost。網路請求經過ResourceDispatcherHost處理之後再通過底層的網路套介面發給web伺服器。
官方設計文檔在這裡:http://dev.chromium.org/developers/design-documents/multi-process-architecture