Thread-safe APIs

スレッド

スレッドは、CPUとコア間で処理能力のバランスを取るために使用されます。 Godotはマルチスレッドをサポートしていますが、エンジン全体ではサポートしていません。

以下は、Godotのさまざまな領域でマルチスレッドを使用する方法の一覧です。

グローバル スコープ

Global Scope singletons are all thread-safe. Accessing servers from threads is supported (for VisualServer and Physics servers, ensure threaded or thread-safe operation is enabled in the project settings!).

これは、サーバーに数十万のインスタンスを作成し、スレッドから制御するコードに最適です。もちろん、これはシーンツリー内ではなく直接使用されるため、多少のコードが必要です。

シーンツリー

Interacting with the active scene tree is NOT thread-safe. Make sure to use mutexes when sending data between threads. If you want to call functions from a thread, the call_deferred function may be used:

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

ただし、アクティブなツリーの外側にシーンチャンク(ツリー配置のノード)を作成することは問題ありません。このようにして、シーンの一部をスレッドで構築またはインスタンス化し、メインスレッドに追加できます:

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

ただし、これはデータをロードするスレッドが1つしかない場合にのみ本当に役立ちます。複数のスレッドからシーンチャンクをロードまたは作成しようとすると、一応は動作する場合もありますが、リソース(Godotで一度だけロードされる)が複数のスレッドによって微調整され、それにより予期しない動作やクラッシュが発生するリスクがあります。

自分が何をしているかを本当に知っていて、単一のリソースが複数のリソースで使用または設定されていないことが確実な場合にのみ、複数のスレッドを使用してシーンデータを生成できます。それ以外の場合は、サーバーAPI(完全にスレッドセーフ)を直接使用するだけにとどめ、シーンやリソースに触れない方が安全です。

GDScriptの配列、辞書

GDScriptでは、複数のスレッドから要素を読み書きすることは可能ですが、コンテナのサイズを変更する操作(要素のサイズ変更、追加、削除)には、ミューテックスをロックする必要があります。

リソース

Modifying a unique resource from multiple threads is not supported. However handling references on multiple threads is supported, hence loading resources on a thread is as well - scenes, textures, meshes, etc - can be loaded and manipulated on a thread and then added to the active scene on the main thread. The limitation here is as described above, one must be careful not to load the same resource from multiple threads at once, therefore it is easiest to use one thread for loading and modifying resources, and then the main thread for adding them.