线程安全的API

线程

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

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

不过,只有当您有**一个**线程加载数据时,这才真正有用。从多个线程加载或创建场景块可能有效,但你要冒着资源被多线程调整的风险(在Godot中只加载一次),从而导致意外行为或崩溃。

只有当您“真正”知道自己在做什么,并且确信一个资源没有被多个资源使用或设置时,才可以使用多个线程来生成场景数据。否则,直接使用服务端的API(它是完全线程安全的)而不接触场景或资源会更安全。

GDScript数组,字典

在GDScript中,可以从多个线程读取和写入元素,但是任何改变容器大小(调整大小,添加或删除元素)的操作都需要锁定互斥。

资源

不支持从多个线程修改唯一资源,但完全支持在线程上加载它们或处理引用。 场景,纹理,网格等可以在线程上加载和操作,然后添加到主线程中的活动场景中。