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.

Thread-safe APIs

Partes_Paralelizáveis

Partes_Paralelizáveis são usadas para equilibrar o poder de processamento entre CPUs e núcleos. Godot suporta multithreading(paralelismo), mas não em todo o Motor.

Abaixo está uma lista de maneiras como o paralelismo(multithreading) pode ser utilizado em diferentes áreas do Godot.

Escopo global

Global Scope singletons(padrão: único) são todos parte_paralelizável segura(thread-safe). O acesso a servidores a partir de partes_paralelizáveis é suportado (para servidores RenderingServer e Physics, certifique-se de que a operação threaded ou thread-safe esteja habilitada nas configurações do projeto!).

Isso os torna ideais para códigos que criam dezenas de milhares de instâncias em servidores e as controlam a partir de partes_paralelizáveis. Claro, isso requer um pouco mais de código, pois é usado diretamente e não na árvore de cena.

Árvore de cena

Interagir com a árvore de cena ativa NÃO é seguro para partes_paralelizáveis. Certifique-se de usar mutexes ao enviar dados entre threads(partes_paralelizáveis). Se você quiser chamar funções de um thread, a função call_deferred pode ser usada:

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

No entanto, criar partes da cena (nós em uma disposição em árvore) fora da árvore ativa é aceitável. Dessa forma, partes de uma cena podem ser construídas ou instanciadas em uma parte_paralelizavel(thread), e depois adicionadas na parte principal_paralelizavel principal(main thread):

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)

Ainda assim, isso só é realmente útil se você tiver uma parte_paralelizável carregando dados. Tentar carregar ou criar partes da cena a partir de várias partes_paralelizáveis pode funcionar, mas você corre o risco de que recursos (que são carregados apenas uma vez no Godot) sejam modificados pelas várias partes_paralelizáveis, resultando em comportamentos inesperados ou falhas.

Use mais de uma parte_paralelizavel(thread) para gerar dados de cena apenas se você realmente souber o que está fazendo e tiver certeza de que um único recurso não está sendo utilizado ou modificado em múltiplas partes_paralelizaveis(threads). Caso contrário, é mais seguro utilizar diretamente a API dos servidores (que é totalmente segura para paralelização = thread-safe) e não mexer em cenas ou recursos.

Renderização

Instancing nodes that render anything in 2D or 3D (such as Sprite) is not thread-safe by default. To make rendering thread-safe, set the Rendering > Driver > Thread Model project setting to Multi-Threaded.

Note that the Multi-Threaded thread model has several known bugs, so it may not be usable in all scenarios.

Você deve evitar chamar funções que envolvam interação direta com a GPU em outras partes_paralelizáveis, como criar novas texturas ou modificar e recuperar dados de imagem, essas operações podem levar a travamentos de desempenho porque requerem sincronização com o RenderingServer, pois os dados precisam ser transmitidos ou atualizados na GPU.

GDScript matrizes, dicionários

No GDScript, ler e escrever elementos de várias partes_paralelizáveis é aceitável, mas qualquer coisa que altere o tamanho do contêiner (redimensionamento, adição ou remoção de elementos) requer o bloqueio de um mutex.

Recursos

Modificar um recurso único a partir de várias partes_paralelizaveis(threads) não é suportado. No entanto, manipular referências em múltiplas partes_paralelizaveis é suportado, o que permite o carregamento de recursos em uma parte_paralelizavel — cenas, texturas, malhas, etc. — que podem ser carregados e manipulados em uma parte_paralelizavel e depois adicionados à cena ativa na parte_paralelizavel principal(main thread). A limitação aqui, conforme descrito acima, é que deve-se ter cuidado para não carregar o mesmo recurso a partir de várias partes_paralelizaveis ao mesmo tempo. Portanto, é mais fácil usar uma parte_paralelizavel para carregar e modificar recursos e, em seguida, a parte_paralelizavel principal(main thread) para adicioná-los.