> Creating threads is a slow operation, especially on Windows.
\- [[Godot]] documentation[^1]
It is best to build a thread pool and re-use threads.
# Environment
## Types
The `Vector` and `PackedArray` types uses atomic operations to maintain thread safety.[^2]
`Variant` is another atomic type.
The documentation does not explain which operations on these types are atomic, but presumably not all of them are.
## Thread Groups
`PROCESS_THREAD_GROUP_INHERIT` is the default for new nodes and they will just inherit whatever thread group their parent has.
`PROCESS_THREAD_GROUP_MAIN_THREAD` ensures that a node evaluates on the main thread. This is necessary for anything which draws to the screen. The top node `root` (or something above it internally) has this set for it.
`PROCESS_THREAD_GROUP_SUB_THREAD` spawns a node in a new thread. Its sub-nodes will follow it to that same thread unless they are specifically set to `PROCESS_THREAD_GROUP_MAIN_THREAD` (which should probably not usually happen).
## Functions
# Working With
## Communicating with the Main Thread
The subthreads need a way to send results back to the main thread.
While this feature is not mentioned in the official documentation for the `call_deferred` function, it can apparently be used to send information back to the main thread.
### Call Deferred by Name
It is a function inherited from `Object` which will run a given function by name during "idle" time *after* the main processing callbacks have finished.
```python
func background_thread_process():
result = 1 + 1
%some_other_node.call_deferred("inbox_function", result)
```
### Call Deferred Callable
Callable objects like function references may be directly invoked.
```python
func background_thread_process():
result = 1 + 1
%some_other_node.inbox_function.call_deferred(result)
```
### Call Deferred Thread Group
This function is run *before* the main processing callbacks and notifications have started.
```python
func background_thread_process():
result = 1 + 1
%some_other_node.call_deferred_thread_group("inbox_function", result)
```
### Call Thread Safe
Acts just like `call`, unless the receiver is running in another thread, then it acts just like `call_deferred`.
This allows a single function to work in both threaded and non-threaded contexts.
```python
func background_thread_process():
result = 1 + 1
%some_other_node.call_thread_safe("inbox_function", result)
```
| Function | Use |
| ------------------------------ | ------------------------------------------------ |
| `set_deferred_thread_group` | Set property *before* processing |
| `set_thread_safe` | Set property *immediately* or *after* processing |
| `notify_deferred_thread_group` | |
| `notify_thread_safe` | |
## Built-In Tools
### Worker Thread Pool
The `WorkerThreadPool`[^3] class provides some basic thread pool functionality.
# Uses
## Tree Building
The documentation[^2] recommends building new trees in a thread and then adding them (with `node.add_child()`) in the main thread.
# Limitations
## Kill Threads
Godot provides no way to kill threads.
# References
- https://docs.godotengine.org/en/stable/classes/class_thread.html
- https://docs.godotengine.org/en/stable/classes/class_node.html#enum-node-processthreadgroup
- https://stackoverflow.com/questions/77053783/a-big-question-on-multi-threading-and-its-nuances-what-is-it-and-how-to-work-wi
## Footnotes
[^1]: https://docs.godotengine.org/en/stable/tutorials/performance/using_multiple_threads.html
[^2]: https://docs.godotengine.org/en/stable/tutorials/performance/thread_safe_apis.html
[^3]: https://docs.godotengine.org/en/stable/classes/class_workerthreadpool.html#class-workerthreadpool