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.
Checking the stable version of the documentation...
스레드(Threads)
스레드
스레드는 CPU와 코어 전반에 걸쳐 처리 능력의 균형을 맞추는 데 사용됩니다. Godot는 멀티스레딩을 지원하지만 전체 엔진에서는 지원하지 않습니다.
다음은 Godot의 다양한 영역에서 멀티스레딩을 사용할 수 있는 방법 목록입니다.
전역 범위
대부분의 Global Scope 싱글톤는 기본적으로 스레드로부터 안전합니다. 스레드에서 서버에 액세스하는 것이 지원됩니다. 그러나 rendering 및 physics 서버의 경우 먼저 프로젝트 설정에서 스레드 안전 작업을 활성화해야 합니다.
따라서 싱글톤는 서버에서 수십만 개의 인스턴스를 생성하고 스레드에서 이를 제어하는 코드에 이상적입니다. 물론 씬 트리 내에서가 아니라 직접 사용되기 때문에 좀 더 많은 코드가 필요합니다.
씬 트리
활성 씬 트리와의 상호 작용은 스레드로부터 안전하지 않습니다. 스레드 간에 데이터를 전송할 때는 뮤텍스를 사용해야 합니다. 스레드에서 함수를 호출하거나 속성을 설정하려면 call_deferred 또는 :ref:`set_deferred <class_Object_method_set_deferred>`를 사용할 수 있습니다.
# Unsafe:
node.add_child(child_node)
# Safe:
node.add_child.call_deferred(child_node)
// Unsafe:
node.AddChild(childNode);
// Safe:
node.CallDeferred(Node.MethodName.AddChild, childNode);
그러나 활성 트리 외부에 씬 청크(트리 배열의 노드)를 생성하는 것은 괜찮습니다. 이런 방식으로 씬의 일부를 스레드에서 구축하거나 인스턴스화한 다음 기본 스레드에 추가할 수 있습니다.
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)
PackedScene enemyScene = GD.Load<PackedScene>("res://EnemyScene.scn");
Node enemy = enemyScene.Instantiate<Node>();
enemy.AddChild(weapon);
world.CallDeferred(Node.MethodName.AddChild, enemy);
하지만 이는 데이터를 로드하는 하나 스레드가 있는 경우에만 정말 유용합니다. 여러 스레드에서 씬 청크를 로드하거나 생성하려는 시도는 성공할 수 있지만 리소스(Godot에서 한 번만 로드됨)가 여러 스레드에 의해 조정되어 예기치 않은 동작이나 충돌이 발생할 위험이 있습니다.
수행 중인 작업을 실제로 알고 있고 단일 리소스가 여러 자원에서 사용되거나 설정되지 않은 것이 확실한 경우에만 둘 이상의 스레드를 사용하여 씬 데이터를 생성하십시오. 그렇지 않으면 씬 또는 리소스를 건드리지 않고 서버 API(완전히 스레드로부터 안전함)를 직접 사용하는 것이 더 안전합니다.
렌더링
2D 또는 3D(예: Sprite2D 또는 MeshInstance3D)로 렌더링하는 노드 인스턴스는 기본적으로 스레드로부터 안전하지 않습니다. 별도의 스레드에서 렌더링 드라이버를 실행하려면 Rendering > Driver > Thread Model 프로젝트 설정을 **별도**로 설정하세요.
별도 스레드 모델에는 몇 가지 알려진 버그가 있으므로 모든 시나리오에서 사용하지 못할 수도 있습니다.
경고
새 텍스처 생성, 이미지 데이터 수정 및 검색 등 다른 스레드에서 GPU와 직접 상호 작용하는 기능을 호출하는 것을 피해야 합니다. 이러한 작업은 GPU에서 데이터를 전송하거나 업데이트해야 하기 때문에 :ref:`RenderingServer<class_RenderingServer>`와의 동기화가 필요하기 때문에 성능 중단으로 이어질 수 있습니다.
물리
물리 시뮬레이션은 기본적으로 스레드로부터 안전하지 않습니다. 별도의 스레드에서 물리 서버를 실행하려면(스레드로부터 안전하도록) 다음 프로젝트 설정을 활성화하십시오.
PhysicsServer2D: Physics > 2D > Run on Separate Thread.
PhysicsServer3D: Physics > 3D > Run on Separate Thread.
GDScript 배열(arrays), 딕셔너리(dictionaries)
GDScript에서는 여러 스레드에서 요소를 읽고 쓰는 것은 괜찮지만 컨테이너 크기를 변경하는 경우(요소 크기 조정, 추가 또는 제거) :ref:`mutex <doc_using_multiple_threads_mutexes>`를 잠가야 합니다.
리소스
여러 스레드에서 고유 리소스를 수정하는 것은 지원되지 않습니다. 그러나 다중 스레드에서의 참조 처리는 지원*됩니다. 따라서 스레드에 리소스를 로드하는 것(장면, 텍스처, 메시 등)도 스레드에 로드하고 조작한 다음 메인 스레드의 활성 씬에 추가할 수 있습니다. 여기서의 제한 사항은 위에서 설명한 대로입니다. 여러 스레드에서 동일한 리소스를 동시에 로드하지 않도록 주의해야 합니다. 따라서 리소스를 로드하고 수정하는 데 **하나* 스레드를 사용한 다음 리소스를 추가하는 데 기본 스레드를 사용하는 것이 가장 쉽습니다.