mirror of
https://github.com/godotengine/godot-docs-l10n.git
synced 2026-01-05 14:10:19 +03:00
249 lines
17 KiB
ReStructuredText
249 lines
17 KiB
ReStructuredText
:github_url: hide
|
||
|
||
.. _class_WorkerThreadPool:
|
||
|
||
WorkerThreadPool
|
||
================
|
||
|
||
**Hérite de :** :ref:`Object<class_Object>`
|
||
|
||
Un singleton qui attribue quelques :ref:`Thread<class_Thread>`\ s au démarrage, utilisé pour décharger des tâches à ces threads.
|
||
|
||
.. rst-class:: classref-introduction-group
|
||
|
||
Description
|
||
-----------
|
||
|
||
The **WorkerThreadPool** singleton allocates a set of :ref:`Thread<class_Thread>`\ s (called worker threads) on project startup and provides methods for offloading tasks to them. This can be used for simple multithreading without having to create :ref:`Thread<class_Thread>`\ s.
|
||
|
||
Tasks hold the :ref:`Callable<class_Callable>` to be run by the threads. **WorkerThreadPool** can be used to create regular tasks, which will be taken by one worker thread, or group tasks, which can be distributed between multiple worker threads. Group tasks execute the :ref:`Callable<class_Callable>` multiple times, which makes them useful for iterating over a lot of elements, such as the enemies in an arena.
|
||
|
||
Here's a sample on how to offload an expensive function to worker threads:
|
||
|
||
|
||
.. tabs::
|
||
|
||
.. code-tab:: gdscript
|
||
|
||
var enemies = [] # An array to be filled with enemies.
|
||
|
||
func process_enemy_ai(enemy_index):
|
||
var processed_enemy = enemies[enemy_index]
|
||
# Expensive logic...
|
||
|
||
func _process(delta):
|
||
var task_id = WorkerThreadPool.add_group_task(process_enemy_ai, enemies.size())
|
||
# Other code...
|
||
WorkerThreadPool.wait_for_group_task_completion(task_id)
|
||
# Other code that depends on the enemy AI already being processed.
|
||
|
||
.. code-tab:: csharp
|
||
|
||
private List<Node> _enemies = new List<Node>(); // A list to be filled with enemies.
|
||
|
||
private void ProcessEnemyAI(int enemyIndex)
|
||
{
|
||
Node processedEnemy = _enemies[enemyIndex];
|
||
// Expensive logic here.
|
||
}
|
||
|
||
public override void _Process(double delta)
|
||
{
|
||
long taskId = WorkerThreadPool.AddGroupTask(Callable.From<int>(ProcessEnemyAI), _enemies.Count);
|
||
// Other code...
|
||
WorkerThreadPool.WaitForGroupTaskCompletion(taskId);
|
||
// Other code that depends on the enemy AI already being processed.
|
||
}
|
||
|
||
|
||
|
||
The above code relies on the number of elements in the ``enemies`` array remaining constant during the multithreaded part.
|
||
|
||
\ **Note:** Using this singleton could affect performance negatively if the task being distributed between threads is not computationally expensive.
|
||
|
||
.. rst-class:: classref-introduction-group
|
||
|
||
Tutoriels
|
||
------------------
|
||
|
||
- :doc:`Utiliser plusieurs fils d'exécution <../tutorials/performance/using_multiple_threads>`
|
||
|
||
- :doc:`Les API sûres pour plusieurs fils d'exécution <../tutorials/performance/thread_safe_apis>`
|
||
|
||
.. rst-class:: classref-reftable-group
|
||
|
||
Méthodes
|
||
----------------
|
||
|
||
.. table::
|
||
:widths: auto
|
||
|
||
+---------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||
| :ref:`int<class_int>` | :ref:`add_group_task<class_WorkerThreadPool_method_add_group_task>`\ (\ action\: :ref:`Callable<class_Callable>`, elements\: :ref:`int<class_int>`, tasks_needed\: :ref:`int<class_int>` = -1, high_priority\: :ref:`bool<class_bool>` = false, description\: :ref:`String<class_String>` = ""\ ) |
|
||
+---------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||
| :ref:`int<class_int>` | :ref:`add_task<class_WorkerThreadPool_method_add_task>`\ (\ action\: :ref:`Callable<class_Callable>`, high_priority\: :ref:`bool<class_bool>` = false, description\: :ref:`String<class_String>` = ""\ ) |
|
||
+---------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||
| :ref:`int<class_int>` | :ref:`get_caller_group_id<class_WorkerThreadPool_method_get_caller_group_id>`\ (\ ) |const| |
|
||
+---------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||
| :ref:`int<class_int>` | :ref:`get_caller_task_id<class_WorkerThreadPool_method_get_caller_task_id>`\ (\ ) |const| |
|
||
+---------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||
| :ref:`int<class_int>` | :ref:`get_group_processed_element_count<class_WorkerThreadPool_method_get_group_processed_element_count>`\ (\ group_id\: :ref:`int<class_int>`\ ) |const| |
|
||
+---------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||
| :ref:`bool<class_bool>` | :ref:`is_group_task_completed<class_WorkerThreadPool_method_is_group_task_completed>`\ (\ group_id\: :ref:`int<class_int>`\ ) |const| |
|
||
+---------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||
| :ref:`bool<class_bool>` | :ref:`is_task_completed<class_WorkerThreadPool_method_is_task_completed>`\ (\ task_id\: :ref:`int<class_int>`\ ) |const| |
|
||
+---------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||
| |void| | :ref:`wait_for_group_task_completion<class_WorkerThreadPool_method_wait_for_group_task_completion>`\ (\ group_id\: :ref:`int<class_int>`\ ) |
|
||
+---------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||
| :ref:`Error<enum_@GlobalScope_Error>` | :ref:`wait_for_task_completion<class_WorkerThreadPool_method_wait_for_task_completion>`\ (\ task_id\: :ref:`int<class_int>`\ ) |
|
||
+---------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||
|
||
.. rst-class:: classref-section-separator
|
||
|
||
----
|
||
|
||
.. rst-class:: classref-descriptions-group
|
||
|
||
Descriptions des méthodes
|
||
--------------------------------------------------
|
||
|
||
.. _class_WorkerThreadPool_method_add_group_task:
|
||
|
||
.. rst-class:: classref-method
|
||
|
||
:ref:`int<class_int>` **add_group_task**\ (\ action\: :ref:`Callable<class_Callable>`, elements\: :ref:`int<class_int>`, tasks_needed\: :ref:`int<class_int>` = -1, high_priority\: :ref:`bool<class_bool>` = false, description\: :ref:`String<class_String>` = ""\ ) :ref:`🔗<class_WorkerThreadPool_method_add_group_task>`
|
||
|
||
Adds ``action`` as a group task to be executed by the worker threads. The :ref:`Callable<class_Callable>` will be called a number of times based on ``elements``, with the first thread calling it with the value ``0`` as a parameter, and each consecutive execution incrementing this value by 1 until it reaches ``element - 1``.
|
||
|
||
The number of threads the task is distributed to is defined by ``tasks_needed``, where the default value ``-1`` means it is distributed to all worker threads. ``high_priority`` determines if the task has a high priority or a low priority (default). You can optionally provide a ``description`` to help with debugging.
|
||
|
||
Returns a group task ID that can be used by other methods.
|
||
|
||
\ **Warning:** Every task must be waited for completion using :ref:`wait_for_task_completion()<class_WorkerThreadPool_method_wait_for_task_completion>` or :ref:`wait_for_group_task_completion()<class_WorkerThreadPool_method_wait_for_group_task_completion>` at some point so that any allocated resources inside the task can be cleaned up.
|
||
|
||
.. rst-class:: classref-item-separator
|
||
|
||
----
|
||
|
||
.. _class_WorkerThreadPool_method_add_task:
|
||
|
||
.. rst-class:: classref-method
|
||
|
||
:ref:`int<class_int>` **add_task**\ (\ action\: :ref:`Callable<class_Callable>`, high_priority\: :ref:`bool<class_bool>` = false, description\: :ref:`String<class_String>` = ""\ ) :ref:`🔗<class_WorkerThreadPool_method_add_task>`
|
||
|
||
Adds ``action`` as a task to be executed by a worker thread. ``high_priority`` determines if the task has a high priority or a low priority (default). You can optionally provide a ``description`` to help with debugging.
|
||
|
||
Returns a task ID that can be used by other methods.
|
||
|
||
\ **Warning:** Every task must be waited for completion using :ref:`wait_for_task_completion()<class_WorkerThreadPool_method_wait_for_task_completion>` or :ref:`wait_for_group_task_completion()<class_WorkerThreadPool_method_wait_for_group_task_completion>` at some point so that any allocated resources inside the task can be cleaned up.
|
||
|
||
.. rst-class:: classref-item-separator
|
||
|
||
----
|
||
|
||
.. _class_WorkerThreadPool_method_get_caller_group_id:
|
||
|
||
.. rst-class:: classref-method
|
||
|
||
:ref:`int<class_int>` **get_caller_group_id**\ (\ ) |const| :ref:`🔗<class_WorkerThreadPool_method_get_caller_group_id>`
|
||
|
||
Renvoie l'ID du groupe de tâche du thread courant appelant cette méthode, ou ``-1`` si invalide ou si le thread courant ne fait pas partie d'un groupe de tâche.
|
||
|
||
.. rst-class:: classref-item-separator
|
||
|
||
----
|
||
|
||
.. _class_WorkerThreadPool_method_get_caller_task_id:
|
||
|
||
.. rst-class:: classref-method
|
||
|
||
:ref:`int<class_int>` **get_caller_task_id**\ (\ ) |const| :ref:`🔗<class_WorkerThreadPool_method_get_caller_task_id>`
|
||
|
||
Returns the task ID of the current thread calling this method, or ``-1`` if the task is a group task, invalid or the current thread is not part of the thread pool (e.g. the main thread).
|
||
|
||
Can be used by a task to get its own task ID, or to determine whether the current code is running inside the worker thread pool.
|
||
|
||
\ **Note:** Group tasks have their own IDs, so this method will return ``-1`` for group tasks.
|
||
|
||
.. rst-class:: classref-item-separator
|
||
|
||
----
|
||
|
||
.. _class_WorkerThreadPool_method_get_group_processed_element_count:
|
||
|
||
.. rst-class:: classref-method
|
||
|
||
:ref:`int<class_int>` **get_group_processed_element_count**\ (\ group_id\: :ref:`int<class_int>`\ ) |const| :ref:`🔗<class_WorkerThreadPool_method_get_group_processed_element_count>`
|
||
|
||
Returns how many times the :ref:`Callable<class_Callable>` of the group task with the given ID has already been executed by the worker threads.
|
||
|
||
\ **Note:** If a thread has started executing the :ref:`Callable<class_Callable>` but is yet to finish, it won't be counted.
|
||
|
||
.. rst-class:: classref-item-separator
|
||
|
||
----
|
||
|
||
.. _class_WorkerThreadPool_method_is_group_task_completed:
|
||
|
||
.. rst-class:: classref-method
|
||
|
||
:ref:`bool<class_bool>` **is_group_task_completed**\ (\ group_id\: :ref:`int<class_int>`\ ) |const| :ref:`🔗<class_WorkerThreadPool_method_is_group_task_completed>`
|
||
|
||
Returns ``true`` if the group task with the given ID is completed.
|
||
|
||
\ **Note:** You should only call this method between adding the group task and awaiting its completion.
|
||
|
||
.. rst-class:: classref-item-separator
|
||
|
||
----
|
||
|
||
.. _class_WorkerThreadPool_method_is_task_completed:
|
||
|
||
.. rst-class:: classref-method
|
||
|
||
:ref:`bool<class_bool>` **is_task_completed**\ (\ task_id\: :ref:`int<class_int>`\ ) |const| :ref:`🔗<class_WorkerThreadPool_method_is_task_completed>`
|
||
|
||
Renvoie ``true`` si la tâche avec l'identifiant donné est terminée.
|
||
|
||
\ **Note :** Vous ne devriez appeler cette méthode que seulement entre l'ajout de la tâche et l'attente de sa complétion.
|
||
|
||
.. rst-class:: classref-item-separator
|
||
|
||
----
|
||
|
||
.. _class_WorkerThreadPool_method_wait_for_group_task_completion:
|
||
|
||
.. rst-class:: classref-method
|
||
|
||
|void| **wait_for_group_task_completion**\ (\ group_id\: :ref:`int<class_int>`\ ) :ref:`🔗<class_WorkerThreadPool_method_wait_for_group_task_completion>`
|
||
|
||
Pause le thread qui appelle cette méthode jusqu'à ce que la tâche du groupe avec l'identifiant donné soit terminée.
|
||
|
||
.. rst-class:: classref-item-separator
|
||
|
||
----
|
||
|
||
.. _class_WorkerThreadPool_method_wait_for_task_completion:
|
||
|
||
.. rst-class:: classref-method
|
||
|
||
:ref:`Error<enum_@GlobalScope_Error>` **wait_for_task_completion**\ (\ task_id\: :ref:`int<class_int>`\ ) :ref:`🔗<class_WorkerThreadPool_method_wait_for_task_completion>`
|
||
|
||
Pauses the thread that calls this method until the task with the given ID is completed.
|
||
|
||
Returns :ref:`@GlobalScope.OK<class_@GlobalScope_constant_OK>` if the task could be successfully awaited.
|
||
|
||
Returns :ref:`@GlobalScope.ERR_INVALID_PARAMETER<class_@GlobalScope_constant_ERR_INVALID_PARAMETER>` if a task with the passed ID does not exist (maybe because it was already awaited and disposed of).
|
||
|
||
Returns :ref:`@GlobalScope.ERR_BUSY<class_@GlobalScope_constant_ERR_BUSY>` if the call is made from another running task and, due to task scheduling, there's potential for deadlocking (e.g., the task to await may be at a lower level in the call stack and therefore can't progress). This is an advanced situation that should only matter when some tasks depend on others (in the current implementation, the tricky case is a task trying to wait on an older one).
|
||
|
||
.. |virtual| replace:: :abbr:`virtual (Cette méthode doit typiquement être redéfinie par l'utilisateur pour avoir un effet.)`
|
||
.. |required| replace:: :abbr:`required (This method is required to be overridden when extending its base class.)`
|
||
.. |const| replace:: :abbr:`const (Cette méthode n'a pas d'effets de bord. Elle ne modifie aucune des variables membres de l'instance.)`
|
||
.. |vararg| replace:: :abbr:`vararg (Cette méthode accepte n'importe quel nombre d'arguments après ceux décris ici.)`
|
||
.. |constructor| replace:: :abbr:`constructor (Cette méthode est utilisée pour construire un type.)`
|
||
.. |static| replace:: :abbr:`static (Cette méthode n'a pas besoin d'instance pour être appelée, elle peut donc être directement appelée en utilisant le nom de la classe.)`
|
||
.. |operator| replace:: :abbr:`operator (Cette méthode décrit un opérateur valide à utiliser avec ce type en tant qu'opérande gauche.)`
|
||
.. |bitfield| replace:: :abbr:`BitField (Cette valeur est un nombre entier composé d'un masque de bits des options suivantes.)`
|
||
.. |void| replace:: :abbr:`void (Aucune valeur de retour.)`
|