Work in progress

The content of this page was not yet updated for Godot 4.4 and may be outdated. If you know how to improve this page or you can confirm that it's up to date, feel free to open a pull request.

執行緒安全的 API

執行緒

執行緒用於平衡多核心 CPU 的運算效能。Godot 支援多執行緒,但不是整個引擎都支援。

以下列出 Godot 不同範疇中可用多執行緒的方式。

全域作用域

Global Scope 單例皆為執行緒安全。支援從執行緒存取伺服器(對於 RenderingServer 與 Physics 伺服器,請確認已在專案設定啟用執行緒或執行緒安全操作!)。

這使其非常適合在伺服器內建立數萬個實體並由執行緒控制的程式碼。當然,這種作法需要額外的程式碼,因為是直接操作,不是透過場景樹。

場景樹

與目前活動場景樹互動**不是**執行緒安全的。在執行緒間傳送資料時,請務必使用互斥鎖(mutex)。若要從執行緒呼叫函式,可使用 call_deferred 函式:

# Unsafe:
node.add_child(child_node)
# Safe:
node.add_child.call_deferred(child_node)

但在現有場景樹之外建立場景片段(以樹狀排列的節點)是沒問題的。如此一來,可以在執行緒中建立或產生部份場景,再於主執行緒新增進場景樹:

var enemy_scene = load("res://enemy_scene.scn")
var enemy = enemy_scene.instantiate()
enemy.add_child(weapon) # Set a weapon.
world.add_child.call_deferred(enemy)

但這僅在你只有**一個**執行緒載入資料時較有用。嘗試從多個執行緒同時載入或建立場景片段雖然可行,但有可能因同一個資源(Godot 僅載入一次)被多個執行緒修改,而導致非預期行為或當機。

只有當你*非常*確定自己操作無誤,且能保證同一資源不會被多個執行緒同時存取或設定時,才建議使用多個執行緒來產生場景資料。否則,直接用伺服器 API(完全執行緒安全),避免直接操作場景或資源會更安全。

算繪

預設情況下,建立可在 2D 或 3D 算繪內容的節點(例如 Sprite)*不是*執行緒安全的。如需讓算繪具備執行緒安全性,請將專案設定 Rendering > Driver > Thread Model 設為 Multi-Threaded

請注意,多執行緒(Multi-Threaded)執行緒模型有多個已知問題,因此不一定適用於所有情境。

你應避免在其他執行緒呼叫與 GPU 直接互動的函式,例如建立新材質、修改或讀取影像資料等。這類操作會因需與 RenderingServer 同步,導致效能延遲,因為資料必須傳送到 GPU 或在 GPU 上更新。

GDScript 陣列、字典

在 GDScript 中,從多個執行緒讀寫元素沒問題,但只要會改變容器大小的操作(如調整大小、加入或移除元素)就必須鎖定互斥鎖。

資源

不支援從多個執行緒同時修改單一資源。但支援於多執行緒間處理引用,因此可在執行緒中載入資源——如場景、材質、網格等——並進行操作,再於主執行緒加入至活動場景。如前所述,需特別注意勿讓多執行緒同時載入同一資源,因此建議僅用**一個**執行緒負責載入與修改資源,主執行緒負責加入。