class to create a task group from a task More...
#include <taskflow/core/task_group.hpp>
Public Member Functions | |
| TaskGroup (const TaskGroup &)=delete | |
| disabled copy constructor | |
| TaskGroup (TaskGroup &&)=delete | |
| disabled move constructor | |
| TaskGroup & | operator= (TaskGroup &&)=delete |
| disabled copy assignment | |
| TaskGroup & | operator= (const TaskGroup &)=delete |
| disabled move assignment | |
| Executor & | executor () |
| obtains the executor that creates this task group | |
| template<typename F> | |
| auto | async (F &&f) |
| runs the given callable asynchronously | |
| template<typename P, typename F> | |
| auto | async (P &¶ms, F &&f) |
| runs the given callable asynchronously | |
| template<typename F> | |
| void | silent_async (F &&f) |
| runs the given function asynchronously without returning any future object | |
| template<typename P, typename F> | |
| void | silent_async (P &¶ms, F &&f) |
| runs the given function asynchronously without returning any future object | |
| template<typename F, typename... Tasks> requires (std::same_as<std::decay_t<Tasks>, AsyncTask> && ...) | |
| auto | dependent_async (F &&func, Tasks &&... tasks) |
| runs the given function asynchronously when the given predecessors finish | |
| template<TaskParameters P, typename F, typename... Tasks> requires (std::same_as<std::decay_t<Tasks>, AsyncTask> && ...) | |
| auto | dependent_async (P &¶ms, F &&func, Tasks &&... tasks) |
| runs the given function asynchronously when the given predecessors finish | |
| template<typename F, typename I> requires (!std::same_as<std::decay_t<I>, AsyncTask>) | |
| auto | dependent_async (F &&func, I first, I last) |
| runs the given function asynchronously when the given range of predecessors finish | |
| template<TaskParameters P, typename F, typename I> requires (!std::same_as<std::decay_t<I>, AsyncTask>) | |
| auto | dependent_async (P &¶ms, F &&func, I first, I last) |
| runs the given function asynchronously when the given range of predecessors finish | |
| template<typename F, typename... Tasks> requires (std::same_as<std::decay_t<Tasks>, AsyncTask> && ...) | |
| tf::AsyncTask | silent_dependent_async (F &&func, Tasks &&... tasks) |
| runs the given function asynchronously when the given predecessors finish | |
| template<TaskParameters P, typename F, typename... Tasks> requires (std::same_as<std::decay_t<Tasks>, AsyncTask> && ...) | |
| tf::AsyncTask | silent_dependent_async (P &¶ms, F &&func, Tasks &&... tasks) |
| runs the given function asynchronously when the given predecessors finish | |
| template<typename F, typename I> requires (!std::same_as<std::decay_t<I>, AsyncTask>) | |
| tf::AsyncTask | silent_dependent_async (F &&func, I first, I last) |
| runs the given function asynchronously when the given range of predecessors finish | |
| template<TaskParameters P, typename F, typename I> requires (!std::same_as<std::decay_t<I>, AsyncTask>) | |
| tf::AsyncTask | silent_dependent_async (P &¶ms, F &&func, I first, I last) |
| runs the given function asynchronously when the given range of predecessors finish | |
| void | corun () |
| corun all tasks spawned by this task group with other workers | |
| void | cancel () |
| cancel all tasks in this task group | |
| bool | is_cancelled () |
| queries if the task group has been cancelled | |
| size_t | size () const |
| queries the number of tasks currently in this task group | |
Friends | |
| class | Executor |
class to create a task group from a task
A task group executes a group of asynchronous tasks. It enables asynchronous task spawning, cooperative execution among worker threads, and naturally supports recursive parallelism. Due to cooperative execution, a task group can only be created by an executor worker; otherwise an exception will be thrown. The code below demonstrates how to use task groups to implement recursive Fibonacci parallelism.
Users must explicitly call tf::TaskGroup::corun() to ensure that all tasks have completed or been properly canceled before leaving the scope of a task group. Failing to do so results in undefined behavior.
| auto tf::TaskGroup::async | ( | F && | f | ) |
runs the given callable asynchronously
| F | callable type |
| f | callable object |
This method creates an asynchronous task that executes the given function with the specified arguments. Unlike tf::Executor::async, the task created here is parented to the task group, where applications can issue tf::TaskGroup::corun to explicitly wait for all asynchronous tasks spawned from the task group to complete. For example:
| auto tf::TaskGroup::async | ( | P && | params, |
| F && | f ) |
runs the given callable asynchronously
| F | callable type |
| P | task parameters type satisfying tf::TaskParameters |
| params | task parameters |
| f | callable |
Similar to tf::TaskGroup::async, but takes a parameter of type tf::TaskParams to initialize the asynchronous task.
|
inline |
cancel all tasks in this task group
Marks the task group as cancelled to stop any not-yet-started tasks in the group from running. Tasks that are already running will continue to completion, but no new tasks belonging to the task group will be scheduled after cancellation.
This example below demonstrates how tf::TaskGroup::cancel() prevents pending tasks in a task group from executing, while allowing already running tasks to complete cooperatively. The first set of tasks deliberately occupies all but one worker thread, ensuring that subsequently spawned tasks remain pending. After invoking tf::TaskGroup::cancel(), these pending tasks are never scheduled, even after the blocked workers are released. A final call to tf::TaskGroup::corun() synchronizes with all tasks in the group, guaranteeing safe completion and verifying that cancellation successfully suppresses task execution.
Note that cancellation is cooperative: tasks should not assume immediate termination. Users must still call tf::TaskGroup::corun() to synchronize with all spawned tasks and ensure safe completion or cancellation. Failing to do so results in undefined behavior.
|
inline |
corun all tasks spawned by this task group with other workers
Coruns all tasks spawned by this task group cooperatively with other workers in the same executor until all these tasks finish. Under cooperative execution, a worker is not preempted. Instead, it continues participating in the work-stealing loop, executing available tasks alongside other workers.
Note that only the parent worker of this task group (the worker who creates it) can call this corun.
| auto tf::TaskGroup::dependent_async | ( | F && | func, |
| I | first, | ||
| I | last ) |
runs the given function asynchronously when the given range of predecessors finish
| F | callable type |
| I | iterator type |
| func | callable object |
| first | iterator to the beginning (inclusive) |
| last | iterator to the end (exclusive) |
The example below creates three asynchronous tasks, A, B, and C, in which task C runs after task A and task B. Task C returns a pair of its tf::AsyncTask handle and a std::future<int> that eventually will hold the result of the execution.
| auto tf::TaskGroup::dependent_async | ( | F && | func, |
| Tasks &&... | tasks ) |
runs the given function asynchronously when the given predecessors finish
| F | callable type |
| Tasks | tasks of type tf::AsyncTask |
| func | callable object |
| tasks | asynchronous tasks on which this execution depends |
The example below creates three asynchronous tasks, A, B, and C, in which task C runs after task A and task B. Task C returns a pair of its tf::AsyncTask handle and a std::future<int> that eventually will hold the result of the execution.
| auto tf::TaskGroup::dependent_async | ( | P && | params, |
| F && | func, | ||
| I | first, | ||
| I | last ) |
runs the given function asynchronously when the given range of predecessors finish
| P | task parameters type satisfying tf::TaskParameters |
| F | callable type |
| I | iterator type |
| params | task parameters |
| func | callable object |
| first | iterator to the beginning (inclusive) |
| last | iterator to the end (exclusive) |
The example below creates three named asynchronous tasks, A, B, and C, in which task C runs after task A and task B. Task C returns a pair of its tf::AsyncTask handle and a std::future<int> that eventually will hold the result of the execution. Assigned task names will appear in the observers of the executor.
| auto tf::TaskGroup::dependent_async | ( | P && | params, |
| F && | func, | ||
| Tasks &&... | tasks ) |
runs the given function asynchronously when the given predecessors finish
| P | task parameters type satisfying tf::TaskParameters |
| F | callable type |
| Tasks | tasks of type tf::AsyncTask |
| params | task parameters |
| func | callable object |
| tasks | asynchronous tasks on which this execution depends |
The example below creates three named asynchronous tasks, A, B, and C, in which task C runs after task A and task B. Task C returns a pair of its tf::AsyncTask handle and a std::future<int> that eventually will hold the result of the execution. Assigned task names will appear in the observers of the executor.
|
inline |
obtains the executor that creates this task group
The running executor of a task group is the executor that creates the task group.
|
inline |
queries if the task group has been cancelled
true if the task group has been marked as cancelled or false otherwiseThis method returns true if the task group has been marked as cancelled via a call to cancel(), and false otherwise.
The cancellation state reflects whether the task group is currently in a cancelled state and does not imply that all tasks have completed or been synchronized. If a task group spawns any task, users must still call corun() to synchronize with all spawned tasks and ensure safe completion or cancellation. Failing to do so results in undefined behavior.
| void tf::TaskGroup::silent_async | ( | F && | f | ) |
runs the given function asynchronously without returning any future object
| F | callable type |
| f | callable |
This function is more efficient than tf::TaskGroup::async and is recommended when the result of the asynchronous task does not need to be accessed via a std::future.
| void tf::TaskGroup::silent_async | ( | P && | params, |
| F && | f ) |
runs the given function asynchronously without returning any future object
| F | callable type |
| params | task parameters |
| f | callable |
Similar to tf::TaskGroup::silent_async, but takes a parameter of type tf::TaskParams to initialize the created asynchronous task.
| tf::AsyncTask tf::TaskGroup::silent_dependent_async | ( | F && | func, |
| I | first, | ||
| I | last ) |
runs the given function asynchronously when the given range of predecessors finish
| F | callable type |
| I | iterator type |
| func | callable object |
| first | iterator to the beginning (inclusive) |
| last | iterator to the end (exclusive) |
This member function is more efficient than tf::TaskGroup::dependent_async and is encouraged to use when you do not want a std::future to acquire the result or synchronize the execution. The example below creates three asynchronous tasks, A, B, and C, in which task C runs after task A and task B.
| tf::AsyncTask tf::TaskGroup::silent_dependent_async | ( | F && | func, |
| Tasks &&... | tasks ) |
runs the given function asynchronously when the given predecessors finish
| F | callable type |
| Tasks | tasks of type tf::AsyncTask |
| func | callable object |
| tasks | asynchronous tasks on which this execution depends |
This member function is more efficient than tf::TaskGroup::dependent_async and is encouraged to use when you do not want a std::future to acquire the result or synchronize the execution. The example below creates three asynchronous tasks, A, B, and C, in which task C runs after task A and task B.
| tf::AsyncTask tf::TaskGroup::silent_dependent_async | ( | P && | params, |
| F && | func, | ||
| I | first, | ||
| I | last ) |
runs the given function asynchronously when the given range of predecessors finish
| F | callable type |
| I | iterator type |
| params | tasks parameters |
| func | callable object |
| first | iterator to the beginning (inclusive) |
| last | iterator to the end (exclusive) |
This member function is more efficient than tf::TaskGroup::dependent_async and is encouraged to use when you do not want a std::future to acquire the result or synchronize the execution. The example below creates three asynchronous tasks, A, B, and C, in which task C runs after task A and task B. Assigned task names will appear in the observers of the executor.
| tf::AsyncTask tf::TaskGroup::silent_dependent_async | ( | P && | params, |
| F && | func, | ||
| Tasks &&... | tasks ) |
runs the given function asynchronously when the given predecessors finish
| F | callable type |
| Tasks | tasks of type tf::AsyncTask |
| params | task parameters |
| func | callable object |
| tasks | asynchronous tasks on which this execution depends |
This member function is more efficient than tf::TaskGroup::dependent_async and is encouraged to use when you do not want a std::future to acquire the result or synchronize the execution. The example below creates three asynchronous tasks, A, B, and C, in which task C runs after task A and task B. Assigned task names will appear in the observers of the executor.
|
inline |
queries the number of tasks currently in this task group
This method returns the number of tasks that belong to the task group at the time of the call. The returned value represents a snapshot and may become outdated immediately, as tasks can be concurrently spawned, started, completed, or canceled while this method is executing. As a result, the value returned by size() should be used for informational or diagnostic purposes only and must not be relied upon for synchronization or correctness.