Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

WorkerThreadPool

繼承: Object

單例,啟動時會分配一些 Thread,可以將工作解除安裝到這些執行緒中執行。

說明

WorkerThreadPool 單例在專案啟動時會分配一組 Thread(稱作工作執行緒)並提供將工作解除安裝至這些執行緒上執行的方法。這樣就能夠簡化多執行緒的使用,不必建立 Thread

工作裡放置的是要讓執行緒執行的 CallableWorkerThreadPool 既可以建立常規任務也可以建立群組工作,常規工作由單個工作執行緒執行,而群組工作可以分佈在多個工作執行緒執行。群組工作會多次執行同一個 Callable,可用於走訪大量的元素,例如場景中的敵人。

以下是將開銷很大的函式解除安裝到工作執行緒執行的例子:

var enemies = [] # 用敵人填充的陣列。

func process_enemy_ai(enemy_index):
    var processed_enemy = enemies[enemy_index]
    # 開銷很大的邏輯……

func _process(delta):
    var task_id = WorkerThreadPool.add_group_task(process_enemy_ai, enemies.size())
    # 其他程式碼……
    WorkerThreadPool.wait_for_group_task_completion(task_id)
    # 要求敵人 AI 已經處理完畢的其他程式碼。

以上程式碼要求 enemies 陣列中的元素個數在多執行緒部分執行時保持不變。

注意:如果分佈到多個執行緒執行的工作在計算方面的開銷並不大,那麼使用這個單例可能對性能有負面影響。

教學

方法

int

add_group_task(action: Callable, elements: int, tasks_needed: int = -1, high_priority: bool = false, description: String = "")

int

add_task(action: Callable, high_priority: bool = false, description: String = "")

int

get_caller_group_id() const

int

get_caller_task_id() const

int

get_group_processed_element_count(group_id: int) const

bool

is_group_task_completed(group_id: int) const

bool

is_task_completed(task_id: int) const

void

wait_for_group_task_completion(group_id: int)

Error

wait_for_task_completion(task_id: int)


方法說明

int add_group_task(action: Callable, elements: int, tasks_needed: int = -1, high_priority: bool = false, description: String = "") 🔗

Adds action as a group task to be executed by the worker threads. The Callable will be called a number of times based on elements, with the first thread calling it with the value 0 as a parameter, and each consecutive execution incrementing this value by 1 until it reaches element - 1.

The number of threads the task is distributed to is defined by tasks_needed, where the default value -1 means it is distributed to all worker threads. high_priority determines if the task has a high priority or a low priority (default). You can optionally provide a description to help with debugging.

Returns a group task ID that can be used by other methods.

Warning: Every task must be waited for completion using wait_for_task_completion() or wait_for_group_task_completion() at some point so that any allocated resources inside the task can be cleaned up.


int add_task(action: Callable, high_priority: bool = false, description: String = "") 🔗

Adds action as a task to be executed by a worker thread. high_priority determines if the task has a high priority or a low priority (default). You can optionally provide a description to help with debugging.

Returns a task ID that can be used by other methods.

Warning: Every task must be waited for completion using wait_for_task_completion() or wait_for_group_task_completion() at some point so that any allocated resources inside the task can be cleaned up.


int get_caller_group_id() const 🔗

Returns the task group ID of the current thread calling this method, or -1 if invalid or the current thread is not part of a task group.


int get_caller_task_id() const 🔗

Returns the task ID of the current thread calling this method, or -1 if the task is a group task, invalid or the current thread is not part of the thread pool (e.g. the main thread).

Can be used by a task to get its own task ID, or to determine whether the current code is running inside the worker thread pool.

Note: Group tasks have their own IDs, so this method will return -1 for group tasks.


int get_group_processed_element_count(group_id: int) const 🔗

返回具有給定 ID 的群組工作的 Callable 已經被工作執行緒執行的次數。

注意:執行緒已經開始執行 Callable 但尚未完成的情況不計算在內。


bool is_group_task_completed(group_id: int) const 🔗

Returns true if the group task with the given ID is completed.

Note: You should only call this method between adding the group task and awaiting its completion.


bool is_task_completed(task_id: int) const 🔗

Returns true if the task with the given ID is completed.

Note: You should only call this method between adding the task and awaiting its completion.


void wait_for_group_task_completion(group_id: int) 🔗

在具有給定 ID 的群組工作完成前暫停呼叫這個方法的執行緒。


Error wait_for_task_completion(task_id: int) 🔗

Pauses the thread that calls this method until the task with the given ID is completed.

Returns @GlobalScope.OK if the task could be successfully awaited.

Returns @GlobalScope.ERR_INVALID_PARAMETER if a task with the passed ID does not exist (maybe because it was already awaited and disposed of).

Returns @GlobalScope.ERR_BUSY if the call is made from another running task and, due to task scheduling, there's potential for deadlocking (e.g., the task to await may be at a lower level in the call stack and therefore can't progress). This is an advanced situation that should only matter when some tasks depend on others (in the current implementation, the tricky case is a task trying to wait on an older one).