深入瞭解Flutter的isolate(3) --- Flutter的thread model(執行緒模型)

小德_Kurt發表於2019-01-11

0x00 前言

Flutter中有一個很重要的概念就是isolate,isolate是由一個執行緒實現的,實現isolate的執行緒由Flutter建立和管理,除了實現isolate的執行緒,Flutter還有其餘的執行緒,本篇文章探討Flutte的threading model(執行緒模型)。

0x01 Flutter Architecture overview

深入瞭解Flutter的isolate(3) --- Flutter的thread model(執行緒模型)
從圖中可以看出Flutter有3部分組成:

  1. Framework(Dart):我們在寫Flutter應用中,直接接觸的
  2. Engine(C/C++):引擎層,提供核心技術,例如:Skia(2D圖形渲染庫);Dart(一個用於垃圾收集的面嚮物件語言的VM,DartVM有自己的執行緒池);shell(不同的平臺有不同的shell,例如有Android和iOS的shell)
  3. Embedder(Platform Specific):嵌入層,為Engine建立和管理執行緒,作用是把Engine的task runners(任務執行器) 執行在嵌入層管理的執行緒上。

0x02 Flutter的task runners的分類

上面講了task runners要執行的執行緒上,這裡的task runners有四種,而且都是執行在不同的執行緒上(可以執行在同一個執行緒上,但是出於效能的因素,不建議這麼做)。

task runners分為四種:

  1. Platform Task Runner
  2. UI Task Runner
  3. GPU Task Runner
  4. IO Task Runner

1. Platform Task Runner

  • Platform Task Runner執行所在的執行緒 對應 平臺的執行緒

    Android iOS
    主執行緒 主執行緒
  • 功能 嵌入層和Engine層的互動,處理平臺(Android/iOS)的訊息

  • 為什麼一定要是平臺的主執行緒? 因為Platform Task Runner的功能是要處理平臺的訊息,但是平臺的API都是隻能在主執行緒呼叫,所以Platform Task Runner執行所在的平臺的執行緒必須是主執行緒

  • 一個Flutter Engine對應一個Platform Thread(一個Flutter應用啟動的時候會建立一個Engine例項,Engine建立的時候會建立一個Platform執行緒供Platform Task Runner使用)

  • 阻塞Platform Thread不會直接導致Flutter應用的卡頓(跟iOS android主執行緒不同)。儘管如此,也不建議在這個Runner執行繁重的操作,長時間卡住Platform Thread應用有可能會被系統Watchdog強殺。

2. UI Task Runner

  • UI Task Runner執行所在的執行緒 對應到 平臺的執行緒

    Android iOS
    子執行緒 子執行緒

    這裡很容易讓大家誤會,因為一看名字,UI Task Runner,第一反應,UI ? 那肯定是在主執行緒裡的,其實並不是,UI Task Runner執行所在的執行緒 對應到 平臺的執行緒,其實是子執行緒

  • 功能

    1)用於執行Dart root isolate程式碼

    2)渲染邏輯,告訴Engine最終的渲染

    3)處理來自Native Plugins的訊息

    4)timers

    5)microtasks

    6)非同步 I/O 操作(sockets, file handles, 等)

  • Root isolate就是執行在這個執行緒上,所以isolate就可以理解為單執行緒,有event loop的架構

  • 阻塞這個執行緒會直接導致Flutter應用卡頓掉幀

  • 為了防止阻塞這個執行緒,我們可以建立其他的isolate,建立的isolate沒有繫結Flutter的功能,只能做資料運算,不能呼叫Flutter的功能,而且建立的isolate的生命週期受Root isolate控制,Root isolate停止,其他的isolate也會停止,而且建立的isolate執行的執行緒,是DartVM裡的執行緒池提供的

3.GPU Task Runner

  • GPU Task Runner執行所在的執行緒 對應到 平臺的執行緒

    Android iOS
    子執行緒 子執行緒
  • 功能

    GPU Task Runner主要用於執行裝置GPU的指令。在UI Task Runner 建立layer tree,在GPU Task Runner將Layer Tree提供的資訊轉化為平臺可執行的GPU指令。

  • UI Task Runner和GPU Task Runner跑在不同的執行緒。GPU Runner會根據目前幀執行的進度去向UI Task Runner要求下一幀的資料,在任務繁重的時候可能會告訴UI Task Runner延遲任務。這種排程機制確保GPU Task Runner不至於過載,同時也避免了UI Task Runner不必要的消耗。

  • 在此執行緒耗時太久的話,會造成Flutter應用卡頓,所以在GPU Task Runner儘量不要做耗時的任務,例如載入圖片的時候,去讀取圖片資料,就不應該放在GPU Task Runner,而是放在接下來要講的IO Task Runner

  • 建議為每一個Engine例項都新建一個專用的GPU Task Runner執行緒。

4. IO Task Runner

  • IO Task Runner執行所在的執行緒 對應到 平臺的執行緒

    Android iOS
    子執行緒 子執行緒
  • 功能

    1)主要功能是從圖片儲存(比如磁碟)中讀取壓縮的圖片格式,將圖片資料進行處理為GPU Runner的渲染做好準備。IO Runner首先要讀取壓縮的圖片二進位制資料(比如PNG,JPEG),將其解壓轉換成GPU能夠處理的格式然後將資料上傳到GPU。 2)載入其他資原始檔

  • 在IO Task Runner不會阻塞Flutter,雖然在載入圖片和資源的時候可能會延遲,但是還是建議為IO Task Runner單獨開一個執行緒。

0x03 各個平臺的執行緒配置

1.iOS

為每個引擎例項的UI,GPU和IO任務執行程式建立專用執行緒。所有引擎例項共享相同的Platform Thread和Platform Task Runner。

2.Android

為每個引擎例項的UI,GPU和IO任務執行程式建立專用執行緒。所有引擎例項共享相同的Platform Thread和Platform Task Runner。

3.Fuchsia

每一個Engine例項都為UI,GPU,IO,Platform Runner建立各自新的執行緒。

4.Flutter Tester (used by flutter test)

UI,GPU,IO和Platform任務執行器使用相同的主執行緒。

相關文章