Work in progress

The content of this page was not yet updated for Godot 4.2 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.

Thread-sichere APIs

Threads

Threads werden verwendet, um die Verarbeitungsleistung zwischen CPUs und Kernen zu verteilen. Godot unterstützt Multithreading, jedoch nicht in der gesamten Engine.

im Folgenden finden Sie eine Liste der Möglichkeiten, wie Multithreading in verschiedenen Bereichen von Godot verwendet werden kann.

Globaler Scope

Singletons im globalen Scope sind alle Thread-sicher. Der Zugriff auf Server von Threads aus wird unterstützt (für RenderingServer und Physikserver muss in den Projekteinstellungen sichergestellt werden, dass der Threading- oder Thread-sichere Betrieb aktiviert ist!).

Dies macht sie ideal für Code, der Zig-Tausende von Instanzen auf Servern erstellt und sie über Threads steuert. Natürlich erfordert es etwas mehr Code, da dieser direkt und nicht im Szenenbaum verwendet wird.

Szenenbaum

Die Interaktion mit dem aktiven Szenenbaum ist NICHT threadsicher. Stellen Sie sicher, dass Sie Mutexe verwenden, wenn Sie Daten zwischen Threads senden. Wenn Sie Funktionen von einem Thread aus aufrufen möchten, kann die Funktion call_deferred verwendet werden:

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

Es ist jedoch in Ordnung, Szenenabschnitte (Nodes in Baumanordnung) außerhalb des aktiven Baums zu erstellen. Auf diese Weise können Teile einer Szene in einem Thread erstellt oder instanziiert und dann im Hauptthread hinzugefügt werden:

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

Dennoch ist dies nur dann wirklich nützlich, wenn Sie einen Thread haben, der Daten lädt. Der Versuch, Szenenabschnitte von mehreren Threads aus zu laden oder zu erstellen, kann zwar funktionieren, aber es besteht die Gefahr, dass Ressourcen (die in Godot nur einmal geladen werden) von den mehreren Threads verändert werden, was zu unerwartetem Verhalten oder Abstürzen führt.

Verwenden Sie nur dann mehr als einen Thread zur Erzeugung von Szenendaten, wenn Sie wirklich wissen, was Sie tun, und sicher sind, dass eine einzelne Ressource nicht in mehreren Threads verwendet oder gesetzt wird. Andernfalls ist es sicherer, die Server-API (die vollständig thread-sicher ist) direkt zu verwenden und weder die Szene noch die Ressourcen anzufassen.

Rendern

Die Instanziierung von Nodes, die irgendetwas in 2D oder 3D rendern (wie z.B. Sprite), ist standardmäßig nicht threadsicher. Um das Rendern threadsicher zu machen, setzen Sie die Projekteinstellung Rendering > Treiber > Thread-Modell auf Multi-Threaded.

Beachten Sie, dass das Multi-Threaded-Thread-Modell mehrere bekannte Bugs enthält, so dass es möglicherweise nicht in allen Szenarien verwendbar ist.

You should avoid calling functions involving direct interaction with the GPU on other threads, such as creating new textures or modifying and retrieving image data, these operations can lead to performance stalls because they require synchronization with the RenderingServer, as data needs to be transmitted to or updated on the GPU.

GDScript Arrays, Dictionarys

In GDScript ist das Lesen und Schreiben von Elementen von mehreren Threads aus in Ordnung, aber alles, was die Größe des Containers ändert (Größenänderung, Hinzufügen oder Entfernen von Elementen), erfordert das Sperren eines Mutex.

Ressourcen

Das Ändern einer einzelnen Ressource von mehreren Threads aus wird nicht unterstützt. Die Handhabung von Referenzen in mehreren Threads wird jedoch unterstützt, also auch das Laden von Ressourcen in einem Thread - Szenen, Texturen, Meshes usw. - können in einem Thread geladen und bearbeitet und dann der aktiven Szene im Hauptthread hinzugefügt werden. Die Einschränkung hierbei ist, wie oben beschrieben, dass man darauf achten muss, nicht dieselbe Ressource von mehreren Threads gleichzeitig zu laden, daher ist es am einfachsten, einen Thread zum Laden und Ändern von Ressourcen und dann den Hauptthread zum Hinzufügen zu verwenden.