Work in progress

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

スレッドセーフAPI

スレッド

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

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

グローバル スコープ

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

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

シーンツリー

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

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

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

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)

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

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

レンダリング

2D または 3D で何かをレンダリングするノード (Sprite など) のインスタンス化は、デフォルトではスレッドセーフではありません。レンダリングをスレッドセーフにするには、プロジェクト設定の レンダリング > ドライバー > スレッドモデルMulti-Threaded に設定します。

マルチスレッドスレッドモデルにはいくつかの既知のバグがあるため、すべてのシナリオで使用できるわけではないことに注意してください。

新しいテクスチャの作成や画像データの変更と取得など、他のスレッドで GPU と直接やり取りする関数を呼び出すことは避けてください。これらの操作は、データを GPU に送信したり GPU 上で更新したりする必要があるため、RenderingServer との同期が必要になるため、パフォーマンスの低下につながる可能性があります。

GDScriptの配列、辞書

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

リソース

複数のスレッドから1つのリソースを変更することはサポートされていません。ただし、複数のスレッドでの参照の処理はサポートされているため、スレッドでのリソースの読み込みも可能です。シーン、テクスチャ、メッシュなどはスレッドで読み込んで操作し、メイン スレッドのアクティブ シーンに追加できます。ここでの制限は上記のとおりです。複数のスレッドから同時に同じリソースを読み込まないように注意する必要があります。したがって、リソースの読み込みと変更には 1 つの スレッドを使用し、次にメイン スレッドを使用してリソースを追加するのが最も簡単です。