class_workerthreadpool.rst 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. :github_url: hide
  2. .. DO NOT EDIT THIS FILE!!!
  3. .. Generated automatically from Godot engine sources.
  4. .. Generator: https://github.com/godotengine/godot/tree/master/doc/tools/make_rst.py.
  5. .. XML source: https://github.com/godotengine/godot/tree/master/doc/classes/WorkerThreadPool.xml.
  6. .. _class_WorkerThreadPool:
  7. WorkerThreadPool
  8. ================
  9. **Inherits:** :ref:`Object<class_Object>`
  10. A singleton that allocates some :ref:`Thread<class_Thread>`\ s on startup, used to offload tasks to these threads.
  11. .. rst-class:: classref-introduction-group
  12. Description
  13. -----------
  14. 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.
  15. 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.
  16. Here's a sample on how to offload an expensive function to worker threads:
  17. .. tabs::
  18. .. code-tab:: gdscript
  19. var enemies = [] # An array to be filled with enemies.
  20. func process_enemy_ai(enemy_index):
  21. var processed_enemy = enemies[enemy_index]
  22. # Expensive logic...
  23. func _process(delta):
  24. var task_id = WorkerThreadPool.add_group_task(process_enemy_ai, enemies.size())
  25. # Other code...
  26. WorkerThreadPool.wait_for_group_task_completion(task_id)
  27. # Other code that depends on the enemy AI already being processed.
  28. .. code-tab:: csharp
  29. private List<Node> _enemies = new List<Node>(); // A list to be filled with enemies.
  30. private void ProcessEnemyAI(int enemyIndex)
  31. {
  32. Node processedEnemy = _enemies[enemyIndex];
  33. // Expensive logic here.
  34. }
  35. public override void _Process(double delta)
  36. {
  37. long taskId = WorkerThreadPool.AddGroupTask(Callable.From<int>(ProcessEnemyAI), _enemies.Count);
  38. // Other code...
  39. WorkerThreadPool.WaitForGroupTaskCompletion(taskId);
  40. // Other code that depends on the enemy AI already being processed.
  41. }
  42. The above code relies on the number of elements in the ``enemies`` array remaining constant during the multithreaded part.
  43. \ **Note:** Using this singleton could affect performance negatively if the task being distributed between threads is not computationally expensive.
  44. .. rst-class:: classref-introduction-group
  45. Tutorials
  46. ---------
  47. - :doc:`Using multiple threads <../tutorials/performance/using_multiple_threads>`
  48. - :doc:`Thread-safe APIs <../tutorials/performance/thread_safe_apis>`
  49. .. rst-class:: classref-reftable-group
  50. Methods
  51. -------
  52. .. table::
  53. :widths: auto
  54. +---------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  55. | :ref:`int<class_int>` | :ref:`add_group_task<class_WorkerThreadPool_method_add_group_task>` **(** :ref:`Callable<class_Callable>` action, :ref:`int<class_int>` elements, :ref:`int<class_int>` tasks_needed=-1, :ref:`bool<class_bool>` high_priority=false, :ref:`String<class_String>` description="" **)** |
  56. +---------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  57. | :ref:`int<class_int>` | :ref:`add_task<class_WorkerThreadPool_method_add_task>` **(** :ref:`Callable<class_Callable>` action, :ref:`bool<class_bool>` high_priority=false, :ref:`String<class_String>` description="" **)** |
  58. +---------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  59. | :ref:`int<class_int>` | :ref:`get_group_processed_element_count<class_WorkerThreadPool_method_get_group_processed_element_count>` **(** :ref:`int<class_int>` group_id **)** |const| |
  60. +---------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  61. | :ref:`bool<class_bool>` | :ref:`is_group_task_completed<class_WorkerThreadPool_method_is_group_task_completed>` **(** :ref:`int<class_int>` group_id **)** |const| |
  62. +---------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  63. | :ref:`bool<class_bool>` | :ref:`is_task_completed<class_WorkerThreadPool_method_is_task_completed>` **(** :ref:`int<class_int>` task_id **)** |const| |
  64. +---------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  65. | void | :ref:`wait_for_group_task_completion<class_WorkerThreadPool_method_wait_for_group_task_completion>` **(** :ref:`int<class_int>` group_id **)** |
  66. +---------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  67. | :ref:`Error<enum_@GlobalScope_Error>` | :ref:`wait_for_task_completion<class_WorkerThreadPool_method_wait_for_task_completion>` **(** :ref:`int<class_int>` task_id **)** |
  68. +---------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  69. .. rst-class:: classref-section-separator
  70. ----
  71. .. rst-class:: classref-descriptions-group
  72. Method Descriptions
  73. -------------------
  74. .. _class_WorkerThreadPool_method_add_group_task:
  75. .. rst-class:: classref-method
  76. :ref:`int<class_int>` **add_group_task** **(** :ref:`Callable<class_Callable>` action, :ref:`int<class_int>` elements, :ref:`int<class_int>` tasks_needed=-1, :ref:`bool<class_bool>` high_priority=false, :ref:`String<class_String>` description="" **)**
  77. 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``.
  78. 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.
  79. Returns a group task ID that can be used by other methods.
  80. .. rst-class:: classref-item-separator
  81. ----
  82. .. _class_WorkerThreadPool_method_add_task:
  83. .. rst-class:: classref-method
  84. :ref:`int<class_int>` **add_task** **(** :ref:`Callable<class_Callable>` action, :ref:`bool<class_bool>` high_priority=false, :ref:`String<class_String>` description="" **)**
  85. 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.
  86. Returns a task ID that can be used by other methods.
  87. .. rst-class:: classref-item-separator
  88. ----
  89. .. _class_WorkerThreadPool_method_get_group_processed_element_count:
  90. .. rst-class:: classref-method
  91. :ref:`int<class_int>` **get_group_processed_element_count** **(** :ref:`int<class_int>` group_id **)** |const|
  92. 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.
  93. \ **Note:** If a thread has started executing the :ref:`Callable<class_Callable>` but is yet to finish, it won't be counted.
  94. .. rst-class:: classref-item-separator
  95. ----
  96. .. _class_WorkerThreadPool_method_is_group_task_completed:
  97. .. rst-class:: classref-method
  98. :ref:`bool<class_bool>` **is_group_task_completed** **(** :ref:`int<class_int>` group_id **)** |const|
  99. Returns ``true`` if the group task with the given ID is completed.
  100. .. rst-class:: classref-item-separator
  101. ----
  102. .. _class_WorkerThreadPool_method_is_task_completed:
  103. .. rst-class:: classref-method
  104. :ref:`bool<class_bool>` **is_task_completed** **(** :ref:`int<class_int>` task_id **)** |const|
  105. Returns ``true`` if the task with the given ID is completed.
  106. .. rst-class:: classref-item-separator
  107. ----
  108. .. _class_WorkerThreadPool_method_wait_for_group_task_completion:
  109. .. rst-class:: classref-method
  110. void **wait_for_group_task_completion** **(** :ref:`int<class_int>` group_id **)**
  111. Pauses the thread that calls this method until the group task with the given ID is completed.
  112. .. rst-class:: classref-item-separator
  113. ----
  114. .. _class_WorkerThreadPool_method_wait_for_task_completion:
  115. .. rst-class:: classref-method
  116. :ref:`Error<enum_@GlobalScope_Error>` **wait_for_task_completion** **(** :ref:`int<class_int>` task_id **)**
  117. Pauses the thread that calls this method until the task with the given ID is completed.
  118. Returns :ref:`@GlobalScope.OK<class_@GlobalScope_constant_OK>` if the task could be successfully awaited.
  119. 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).
  120. 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).
  121. .. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
  122. .. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
  123. .. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
  124. .. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`
  125. .. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`
  126. .. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`
  127. .. |bitfield| replace:: :abbr:`BitField (This value is an integer composed as a bitmask of the following flags.)`