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.
Checking the stable version of the documentation...
WorkerThreadPool
Eredita: Object
Un singleton che alloca alcuni Thread all'avvio, usato per scaricare delle attività a questi thread.
Descrizione
Il singleton WorkerThreadPool assegna un insieme di Thread (chiamati thread di lavoro) all'avvio del progetto e fornisce metodi per scaricare attività a essi. Questo può essere utilizzato per multithreading semplice senza dover creare i Thread.
Le attività mantengono il Callable da eseguire dai thread. WorkerThreadPool può essere utilizzato per creare attività regolari, che saranno presi da un singolo thread di lavoro, o attività di gruppo, che possono essere distribuiti tra più thread di lavoro. Le attività di gruppo eseguono più volte il Callable, il che le rende utili per iterare su molti elementi, come nemici in un'arena.
Ecco un esempio su come scaricare una funzione costosa ai thread di lavoro:
var enemies = [] # Un array da riempire con nemici.
func process_enemy_ai(enemy_index):
var processed_enemy = enemies[enemy_index]
# Logica costosa...
func _process(delta):
var task_id = WorkerThreadPool.add_group_task(process_enemy_ai, enemies.size())
# Altro codice...
WorkerThreadPool.wait_for_group_task_completion(task_id)
# Altro codice che dipende sull'AI del nemico è già in elaborazione.
private List<Node> _enemies = new List<Node>(); // Una lista da riempire con nemici.
private void ProcessEnemyAI(int enemyIndex)
{
Node processedEnemy = _enemies[enemyIndex];
// Logica costosa qui.
}
public override void _Process(double delta)
{
long taskId = WorkerThreadPool.AddGroupTask(Callable.From<int>(ProcessEnemyAI), _enemies.Count);
// Altro codice...
WorkerThreadPool.WaitForGroupTaskCompletion(taskId);
// Altro codice che dipende sull'AI del nemico è già in elaborazione.
}
Il codice di sopra assume che il numero di elementi nell'array enemies rimanga costante durante la parte di multithread.
Nota: Utilizzare questo singleton potrebbe influenzare negativamente le prestazioni se il compito che viene distribuito tra i thread non è computazionalmente costoso.
Tutorial
Metodi
add_group_task(action: Callable, elements: int, tasks_needed: int = -1, high_priority: bool = false, description: String = "") |
|
add_task(action: Callable, high_priority: bool = false, description: String = "") |
|
get_caller_group_id() const |
|
get_caller_task_id() const |
|
get_group_processed_element_count(group_id: int) const |
|
is_group_task_completed(group_id: int) const |
|
is_task_completed(task_id: int) const |
|
void |
wait_for_group_task_completion(group_id: int) |
wait_for_task_completion(task_id: int) |
Descrizioni dei metodi
int add_group_task(action: Callable, elements: int, tasks_needed: int = -1, high_priority: bool = false, description: String = "") 🔗
Aggiunge action come attività di gruppo da eseguire dai thread di lavoro. Il Callable verrà chiamato un certo numero di volte in base a elements, con il primo thread che lo chiama con il valore 0 come parametro e ogni esecuzione consecutiva incrementa questo valore di 1 fino a raggiungere elemento - 1.
Il numero di thread a cui viene distribuita l'attività è definito da tasks_needed, dove il valore predefinito -1 significa che viene distribuito a tutti i thread di lavoro. high_priority determina se l'attività ha una priorità alta o bassa (predefinita). Facoltativamente, puoi fornire una descrizione (description) per facilitare il debug.
Restituisce un ID attività di gruppo che può essere utilizzato da altri metodi.
Attenzione: È necessario attendere il completamento di ogni attività attraverso wait_for_task_completion() o wait_for_group_task_completion() a un certo punto in modo che eventuali risorse allocate all'interno dell'attività possano essere ripulite.
int add_task(action: Callable, high_priority: bool = false, description: String = "") 🔗
Aggiunge action come attività da eseguire tramite un thread di lavoro. high_priority determina se l'attività ha una priorità alta o bassa (predefinita). Facoltativamente, puoi fornire una descrizione (description) per facilitare il debug.
Restituisce un ID attività che può essere utilizzato da altri metodi.
Attenzione: È necessario attendere il completamento di ogni attività attraverso wait_for_task_completion() o wait_for_group_task_completion() a un certo punto in modo che eventuali risorse allocate all'interno dell'attività possano essere ripulite.
int get_caller_group_id() const 🔗
Restituisce l'ID del gruppo di attività del thread attuale che chiama questo metodo oppure -1 se non è valido o se il thread attuale non fa parte di un gruppo di attività.
int get_caller_task_id() const 🔗
Restituisce l'ID attività del thread attuale che chiama questo metodo, oppure -1 se l'attività è un'attività di gruppo, non valida o se il thread attuale non fa parte del pool di thread (ad esempio, il thread principale).
È possibile utilizzato da un'attività per ottenere il proprio ID attività o per determinare se il codice attuale è in esecuzione all'interno del pool di thread worker.
Nota: Le attività di gruppo hanno i propri ID, quindi questo metodo restituirà -1 per le attività di gruppo.
int get_group_processed_element_count(group_id: int) const 🔗
Restituisce quante volte il Callable dell'attività di gruppo con l'ID specificato è stato già eseguito dai thread di lavoro.
Nota: Se un thread ha iniziato a eseguire il Callable ma deve ancora terminare, non sarà conteggiato.
bool is_group_task_completed(group_id: int) const 🔗
Restituisce true se l'attività di gruppo con l'ID specificato è completata.
Nota: Si dovrebbe solo chiamare questo metodo tra l'aggiunta dell'attività di gruppo e in attesa del suo completamento.
bool is_task_completed(task_id: int) const 🔗
Restituisce true se l'attività con l'ID fornito è completata.
Nota: Si dovrebbe solo chiamare questo metodo tra l'aggiunta dell'attività e in attesa del suo completamento.
void wait_for_group_task_completion(group_id: int) 🔗
Mette in pausa il thread che richiama questo metodo finché non viene completata l'attività di gruppo con l'ID specificato.
Error wait_for_task_completion(task_id: int) 🔗
Mette in pausa il thread che richiama questo metodo finché non viene completata l'attività con l'ID specificato.
Restituisce @GlobalScope.OK se è stato possibile attendere l'attività correttamente.
Restituisce @GlobalScope.ERR_INVALID_PARAMETER se un'attività con l'ID passato non esiste (forse perché era già stata attesa ed eliminata).
Restituisce @GlobalScope.ERR_BUSY se la chiamata viene effettuata da un'altra attività in esecuzione e, a causa della pianificazione delle attività, c'è il potenziale per un deadlock (ad esempio, l'attività da attendere potrebbe essere a un livello inferiore nello stack di chiamate e quindi non può procedere). Questa è una situazione avanzata che dovrebbe avere importanza solo quando alcune attività dipendono da altre (nell'implementazione attuale, il caso complicato è un'attività che tenta di attendere una più vecchia).