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

Потоки

Потоки використовуються для балансування потужності процесорів і ядер. 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)

Тим не менш, це дійсно корисно, лише якщо у вас є один потік даних для завантаження. Спроба завантажити або створити фрагменти сцени з кількох потоків може спрацювати, але ви ризикуєте, що ресурси (які завантажуються лише один раз у Godot) будуть налаштовані кількома потоками, що призведе до неочікуваної поведінки або збоїв.

Використовуйте більше ніж один потік для генерації даних сцени, лише якщо ви справді знаєте, що робите, і ви впевнені, що один ресурс не використовується або встановлений у кількох. В іншому випадку вам безпечніше просто використовувати API серверів (який є повністю потоково-безпечним) безпосередньо і не торкатися сцени чи ресурсів.

Рендеринг

Вузли створення екземплярів, які відображають будь-що у 2D або 3D (наприклад, Sprite), за замовчуванням є не потокобезпечними. Щоб зробити візуалізацію потоково-безпечною, установіть для параметра проекту Rendering > Driver > Thread Model значення Multi-Threaded.

Зауважте, що багатопотокова модель потоку має кілька відомих помилок, тому її можна використовувати не в усіх сценаріях.

Слід уникати виклику функцій, що передбачають безпосередню взаємодію з графічним процесором в інших потоках, таких як створення нових текстур або модифікація та отримання даних зображення, ці операції можуть призвести до падіння продуктивності, оскільки вони вимагають синхронізації з RenderingServer, оскільки дані потрібно передавати на графічний процесор або оновлювати на ньому.

Масиви GDScript, словники

У GDScript можна читати та записувати елементи з кількох потоків, але все, що змінює розмір контейнера (зміна розміру, додавання або видалення елементів), потребує блокування м’ютексу.

Ресурси

Модифікація унікального ресурсу з декількох потоків не підтримується. Проте робота з посиланнями у декількох потоках підтримується, отже, завантаження ресурсів у потоці також підтримується - сцени, текстури, сіті тощо можуть бути завантажені та оброблені у потоці, а потім додані до активної сцени у головному потоці. Обмеження тут таке, як описано вище, потрібно бути обережним, щоб не завантажувати один і той самий ресурс з декількох потоків одночасно, тому найпростіше використовувати один потік для завантаження і модифікації ресурсів, а потім основний потік для їхнього додавання.