Thread-safe APIs

线程

Threads are used to balance processing power across CPUs and cores. Godot supports multithreading, but not in the whole engine.

下面是可以在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:

  1. # Unsafe:
  2. node.add_child(child_node)
  3. # Safe:
  4. node.call_deferred("add_child", child_node)

但是,可以在激活的场景树外创建场景块(以树形式排列的节点)。 这样,可以在线程中构建或实例化部分场景,然后将其添加到主线程中:

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

不过,只有当您有**一个**线程加载数据时,这才真正有用。从多个线程加载或创建场景块可能有效,但你要冒着资源被多线程调整的风险(在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.