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.

API thread-safe

Threads

I thread servono per bilanciare la potenza di elaborazione tra CPU e core. Godot supporta il multithreading, ma non nell'intero motore.

Di seguito è riportato un elenco dei modi in cui si può utilizzare il multithreading in diverse aree di Godot.

Ambito globale

La maggior parte dei singleton del Global Scope sono thread-safe di norma. L'accesso ai server dai thread è supportato. Tuttavia, per i server di rendering e di fisica, è necessario prima abilitare il funzionamento thread-safe nelle impostazioni del progetto.

Questo rende i singleton ideali per codice che crea decine di migliaia di istanze nei server e le controlla dai thread. Naturalmente, richiede un po' più di codice, poiché è utilizzato direttamente e non all'interno dell'albero di scene.

Albero di scene

Interagire con l'albero di scene attivo non è thread-safe. Assicurati di utilizzare i mutex quando invii dati tra più thread. Se desideri chiamare funzioni o impostare proprietà da un thread, potresti usare call_deferred o set_deferred:

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

Tuttavia, va bene creare frammenti di scene (nodi disposti ad albero) fuori dall'albero attivo. In questo modo, è possibile creare o istanziare parti di una scena in un thread, per poi aggiungerle al thread principale:

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)

In ogni caso, questo è davvero utile solo se hai un solo thread che carica i dati. Tentare di caricare o creare frammenti di scene dai thread potrebbe funzionare, ma si rischia che le risorse (che in Godot vengono caricate una sola volta) vengano alterate dai vari thread, causando comportamenti imprevisti o arresti anomali.

Utilizza più di un thread per generare i dati delle scene solo se sai davvero cosa stai facendo e sei sicuro che una singola risorsa non sia utilizzata o impostata in più thread. Altrimenti, è più sicuro utilizzare direttamente l'API dei server (che sono completamente thread-safe) e non toccare le scena o le risorse.

Renderer

Istanziare nodi che renderizzano qualcosa in 2D o 3D (come Sprite2D o MeshInstance3D) non è thread-safe normalmente. Per eseguire il driver di rendering su un thread separato, impostare l'impostazione del progetto Rendering > Driver > Thread Model su Separate.

Si noti che il modello di thread Separate ha diversi bug noti, pertanto potrebbe non essere utilizzabile in tutti gli scenari.

Avvertimento

È consigliabile evitare di chiamare funzioni che richiedono di interagire direttamente con la GPU su altri thread, come creare nuove texture o modificare e recuperare dati di immagini. Queste operazioni potrebbero rallentare le prestazioni perché richiedono la sincronizzazione con il RenderingServer, in quanto i dati si devono trasmettere o aggiornare sulla GPU.

Fisica

La simulazione della fisica non è thread-safe normalmente. Per eseguire i server di fisica su thread separati (rendendoli thread-safe), abilitare le seguenti impostazioni del progetto:

Array e dizionari in GDScript

In GDScript, leggere e scrivere elementi da più thread va bene, ma qualsiasi operazione che cambi le dimensioni di un contenitore (ridimensionamento, aggiunta o rimozione di elementi) richiede il blocco di un mutex.

Risorse

Modificare una singola risorsa da più thread non è supportato. Tuttavia, gestire i riferimenti su più thread è supportato. Ecco perché anche caricare le risorse su un thread è supportato: è possibile caricare e manipolare scene, texture, mesh, ecc. su un thread e poi aggiungerle alla scena attiva sul thread principale. La limitazione in questo caso è quella descritta sopra: bisogna fare attenzione a non caricare la stessa risorsa da più thread alla volta. Pertanto, è più semplice utilizzare un solo thread per caricare e modificare le risorse, e poi il thread principale per aggiungerle.