Files
godot-docs-l10n/classes/ru/class_workerthreadpool.rst

249 lines
21 KiB
ReStructuredText
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

:github_url: hide
.. _class_WorkerThreadPool:
WorkerThreadPool
================
**Наследует:** :ref:`Object<class_Object>`
Синглтон, который выделяет некоторые :ref:`Thread<class_Thread>` при запуске, используемый для разгрузки задач в эти потоки.
.. rst-class:: classref-introduction-group
Описание
----------------
Синглтон **WorkerThreadPool** выделяет набор :ref:`Thread<class_Thread>` (называемых рабочими потоками) при запуске проекта и предоставляет методы для выгрузки задач в них. Это можно использовать для простой многопоточности без необходимости создания :ref:`Thread<class_Thread>`.
Задачи содержат :ref:`Callable<class_Callable>` для запуска потоками. **WorkerThreadPool** можно использовать для создания обычных задач, которые будут приниматься одним рабочим потоком, или групповых задач, которые могут быть распределены между несколькими рабочими потоками. Групповые задачи выполняют :ref:`Callable<class_Callable>` несколько раз, что делает их полезными для итерации по множеству элементов, таких как враги на арене.
Вот пример того, как выгрузить дорогостоящую функцию в рабочие потоки:
.. tabs::
.. code-tab:: gdscript
var enemies = [] # Массив, который нужно заполнить врагами.
func process_enemy_ai(enemy_index):
var processed_enemy = enemies[enemy_index]
# Дорогая логика...
func _process(delta):
var task_id = WorkerThreadPool.add_group_task(process_enemy_ai, enemies.size())
# Другой код...
WorkerThreadPool.wait_for_group_task_completion(task_id)
# Другой код, зависящий от уже обрабатываемого ИИ врага.
.. code-tab:: csharp
private List<Node> _enemies = new List<Node>(); // Массив, который нужно заполнить врагами.
private void ProcessEnemyAI(int enemyIndex)
{
Node processedEnemy = _enemies[enemyIndex];
// Дорогая логика...
}
public override void _Process(double delta)
{
long taskId = WorkerThreadPool.AddGroupTask(Callable.From<int>(ProcessEnemyAI), _enemies.Count);
// Другой код...
WorkerThreadPool.WaitForGroupTaskCompletion(taskId);
// Другой код, зависящий от уже обрабатываемого ИИ врага.
}
Приведенный выше код полагается на то, что количество элементов в массиве ``enemies`` остается постоянным во время многопоточной части.
\ **Примечание:** Использование этого синглтона может отрицательно повлиять на производительность, если задача, распределяемая между потоками, не является вычислительно затратной.
.. rst-class:: classref-introduction-group
Обучающие материалы
--------------------------------------
- :doc:`Использование многопоточности <../tutorials/performance/using_multiple_threads>`
- :doc:`Потокобезопасные API <../tutorials/performance/thread_safe_apis>`
.. rst-class:: classref-reftable-group
Методы
------------
.. 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
Описания метода
------------------------------
.. _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>`
Добавляет ``action`` в качестве групповой задачи для выполнения рабочими потоками. :ref:`Callable<class_Callable>` будет вызываться несколько раз на основе ``elements``, при этом первый поток вызывает его со значением ``0`` в качестве параметра, а каждое последующее выполнение увеличивает это значение на 1, пока не достигнет ``element - 1``.
Количество потоков, на которые распределяется задача, определяется ``tasks_needed``, где значение по умолчанию ``-1`` означает, что она распределяется на все рабочие потоки. ``high_priority`` определяет, имеет ли задача высокий или низкий приоритет (по умолчанию). Вы можете дополнительно указать ``description`` для помощи в отладке.
Возвращает идентификатор групповой задачи, который может использоваться другими методами.
\ **Предупреждение:** В какой-то момент необходимо дождаться завершения каждой задачи с помощью :ref:`wait_for_task_completion()<class_WorkerThreadPool_method_wait_for_task_completion>` или :ref:`wait_for_group_task_completion()<class_WorkerThreadPool_method_wait_for_group_task_completion>`, чтобы можно было освободить все выделенные внутри задачи ресурсы.
.. 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>`
Добавляет ``action`` в качестве задачи для выполнения рабочим потоком. ``high_priority`` определяет, имеет ли задача высокий или низкий приоритет (по умолчанию). При желании вы можете указать ``description`` для помощи в отладке.
Возвращает идентификатор задачи, который может использоваться другими методами.
\ **Предупреждение:** Каждая задача должна быть дожидаться завершения с помощью :ref:`wait_for_task_completion()<class_WorkerThreadPool_method_wait_for_task_completion>` или :ref:`wait_for_group_task_completion()<class_WorkerThreadPool_method_wait_for_group_task_completion>` в какой-то момент, чтобы можно было очистить любые выделенные ресурсы внутри задачи.
.. 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>`
Возвращает ID идентификатор группы задач текущего потока, вызывающего этот метод, или ``-1``, если недопустимо или текущий поток не является частью группы задач.
.. 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>`
Возвращает ID идентификатор задачи текущего потока, вызывающего этот метод, или ``-1``, если задача является групповой задачей, недопустимой или текущий поток не является частью пула потоков (например, основного потока).
Может использоваться задачей для получения собственного идентификатора задачи или для определения того, выполняется ли текущий код внутри пула рабочих потоков.
\ **Примечание:** Групповые задачи имеют собственные ID идентификаторы, поэтому этот метод вернет ``-1`` для групповых задач.
.. 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>`
Возвращает, сколько раз :ref:`Callable<class_Callable>` групповой задачи с указанным идентификатором уже был выполнен рабочими потоками.
\ **Примечание:** Если поток начал выполнение :ref:`Callable<class_Callable>`, но еще не завершил его, он не будет засчитан.
.. 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>`
Возвращает ``true``, если групповая задача с указанным идентификатором завершена.
\ **Примечание:** Вызвать этот метод следует только между добавлением групповой задачи и ожиданием ее завершения.
.. 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>`
Возвращает ``true``, если задача с указанным идентификатором завершена.
\ **Примечание:** Вызвать этот метод следует только между добавлением задачи и ожиданием ее завершения.
.. 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>`
Приостанавливает поток, вызывающий этот метод, до тех пор, пока не будет завершена групповая задача с указанным идентификатором.
.. 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>`
Приостанавливает поток, вызывающий этот метод, до тех пор, пока задача с указанным идентификатором не будет завершена.
Возвращает :ref:`@GlobalScope.OK<class_@GlobalScope_constant_OK>`, если задача может быть успешно ожидана.
Возвращает :ref:`@GlobalScope.ERR_INVALID_PARAMETER<class_@GlobalScope_constant_ERR_INVALID_PARAMETER>`, если задача с переданным идентификатором не существует (возможно, потому что она уже была ожидаема и удалена).
Возвращает :ref:`@GlobalScope.ERR_BUSY<class_@GlobalScope_constant_ERR_BUSY>`, если вызов выполняется из другой запущенной задачи и из-за планирования задач существует вероятность взаимоблокировки (например, задача для ожидания может находиться на более низком уровне в стеке вызовов и, следовательно, не может выполняться). Это сложная ситуация, которая должна иметь значение только тогда, когда некоторые задачи зависят от других (в текущей реализации сложный случай — это задача, пытающаяся ждать более старую).
.. |virtual| replace:: :abbr:`virtual (Этот метод обычно должен быть переопределен пользователем, чтобы иметь какой-либо эффект.)`
.. |required| replace:: :abbr:`required (This method is required to be overridden when extending its base class.)`
.. |const| replace:: :abbr:`const (Этот метод не имеет побочных эффектов. Он не изменяет ни одну из переменных-членов экземпляра.)`
.. |vararg| replace:: :abbr:`vararg (Этот метод принимает любое количество аргументов после описанных здесь.)`
.. |constructor| replace:: :abbr:`constructor (Этот метод используется для создания типа.)`
.. |static| replace:: :abbr:`static (Этот метод не нуждается в вызове экземпляра, поэтому его можно вызвать напрямую, используя имя класса.)`
.. |operator| replace:: :abbr:`operator (Этот метод описывает допустимый оператор для использования с этим типом в качестве левого операнда.)`
.. |bitfield| replace:: :abbr:`BitField (Это значение является целым числом, составленным как битовая маска следующих флагов.)`
.. |void| replace:: :abbr:`void (Нет возвращаемого значения.)`