スレッドセーフAPI

スレッド

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

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

グローバル スコープ

Global Scope シングルトンはすべてスレッドセーフです。スレッドからサーバーへのアクセスがサポートされています(VisualServerおよびPhysicsサーバーの場合、プロジェクト設定でスレッドセーフまたはスレッドセーフ操作が有効になっていることを確認してください!)。

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

シーンツリー

アクティブなシーンツリーとの対話は、スレッドセーフではありません。スレッド間でデータを送信するときは、必ずミューテックスを使用してください。スレッドから関数を呼び出したい場合は、*call_deferred * 関数を使用できます:

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

リソース

複数のスレッドから一意のリソースを変更することはサポートされていませんが、スレッドへのリソースの読み込みや参照の処理は完全にサポートされています。シーン、テクスチャ、メッシュなどをスレッドでロードおよび操作し、メインスレッドのアクティブシーンに追加できます。