CEF3開發者系列之進程和線程

  CEF3是一個多進程架構框架,若是有了解過chromium的進程架構的,那麼就很容易瞭解CEF3的多進程了。打開CEF3源代碼中發佈的cefclient實例,若是打開的頁面帶有flash或者其餘插件。在任務管理其中能夠看到四個進程,顯示出命令行列。能夠看到一個主進程,通常主進程是Browser進程,其餘的分別是渲染進程(Render),GPU加速進程(GPU),插件進程(NPAPI或者PPAPI)。git

Browser進程:被定義爲主進程,負責窗口管理,界面繪製和網絡交互。github

Render 進程:Blink的渲染和Js的執行被放在一個獨立的Render 進程中;除此以外,Render進程還負責Js Binding和對Dom節點的訪問。 默認的進程模型中,會爲每一個標籤頁建立一個新的Render進程。數組

NPAPI插件進程:按需建立,每種類型的插件只會有一個進程,每一個插件進程能夠被多個Render進程共享;瀏覽器

Pepper插件進程:同NPAPI插件進程,不一樣的是爲Pepper插件而建立的進程;安全

GPU進程:按需建立,最多隻有一個,當且僅當GPU硬件加速打開的時候纔會被建立,主要用於對3D加速調用的實現。網絡

  多進程的好處不少,在瀏覽器中最主要的好處是當一個頁面或者插件崩潰或假死,不會給其餘頁面帶來影響。CEF3的進程之間能夠經過IPC進行通訊。Browser和Render進程能夠經過發送異步消息進行雙向通訊。甚至在Render進程能夠註冊在Browser進程響應的異步JavaScript API。在CEF3中,Browser和Render進程間能夠經過SendProcessMessage(CefProcessId target_process,  CefRefPtr<CefProcessMessage> message)函數實現消息傳遞。多線程

  默認狀況下,主應用程序會被屢次啓動運行各自獨立的進程。經過傳遞不一樣的命令行參數給CefExecuteProcess函數實現的。若是主應用程序很大,加載時間比較長,或者不能在非瀏覽器進程裏使用,則宿主程序可以使用獨立的可執行文件去運行這些進程。這能夠經過配置 CefSettings.browser_subprocess_path變量作到。更閉包

  chromium自己支持多種進程模型,但CEF3主要是模型是兩種:單進程和爲每一個標籤建立一個進程。後一種是缺省行爲,前邊一種可設置。經過設置命令行的--single-process,CEF3就能夠支持用於調試目的的單進程運行模型。支持的平臺爲:Windows,Mac OS X 和Linux。架構

 

  一圖解千語,下圖給出了缺省的chromium瀏覽器的進程模型。方框表明進程,鏈接線表明IPC進程間通訊。app

 

 

  因爲關於cef3進程架構的講解不多,我的猜想CEF3的進程架構和chromium應該差很少,畢竟CEF3是基於chromium的框架。更多和進程相關的內容能夠網上搜索「chromium多進程架構」。

 

  在CEF3中,每一個進程都會運行多個線程。完整的線程類型表請參照cef_thread_id_t

typedef enum {
// BROWSER PROCESS THREADS -- Only available in the browser process.

  ///
  // The main thread in the browser. This will be the same as the main
  // application thread if CefInitialize() is called with a
  // CefSettings.multi_threaded_message_loop value of false.
  ///
  TID_UI,

 

  // Used to interact with the database.
  TID_DB,

  ///
  // Used to interact with the file system.
  ///
  TID_FILE,

  // Used for file system operations that block user interactions.
  // Responsiveness of this thread affects users.
  TID_FILE_USER_BLOCKING,

  ///
  // Used to launch and terminate browser processes.
  ///
  TID_PROCESS_LAUNCHER,

  // Used to handle slow HTTP cache operations.
  TID_CACHE,

  // Used to process IPC and network messages.
  TID_IO,

// RENDER PROCESS THREADS -- Only available in the render process.

  ///
  // The main thread in the renderer. Used for all WebKit and V8 interaction.
  ///
  TID_RENDERER,
} cef_thread_id_t;

 

在Browser進程中包含以下主要的線程:

      • TID_UI 線程是瀏覽器的主線程。若是應用程序在調用調用CefInitialize()時,傳遞CefSettings.multi_threaded_message_loop=false,這個線程也是應用程序的主線程。
      • TID_IO 線程主要負責處理IPC消息以及網絡通訊。
      • TID_FILE 線程負責與文件系統交互。

因爲CEF採用多線程架構,有必要使用鎖和閉包來保證數據的線程安全語義。IMPLEMENT_LOCKING定義提供了Lock()和 Unlock()方法以及AutoLock對象來保證不一樣代碼塊同步訪問數據。CefPostTask函數組支持簡易的線程間異步消息傳遞。更多信息,請參考Posting Tasks章節。

能夠經過CefCurrentlyOn()方法判斷當前所在的線程環境,cefclient工程使用下面的定義來確保方法在指望的線程中被執行。

#define REQUIRE_UI_THREAD()   ASSERT(CefCurrentlyOn(TID_UI)); #define REQUIRE_IO_THREAD()   ASSERT(CefCurrentlyOn(TID_IO)); #define REQUIRE_FILE_THREAD() ASSERT(CefCurrentlyOn(TID_FILE));

相關文章
相關標籤/搜索