Waiting for Individual Tasks in task_group#
Note
To enable this extension, define the TBB_PREVIEW_TASK_GROUP_EXTENSIONS macro with a value of 1.
When available and enabled, the feature-test macro TBB_HAS_TASK_GROUP_WAIT_FOR_SINGLE_TASK is defined.
Description#
This feature extends the task_group and task_arena classes with functions
that wait for the completion of a single task, identified by a task_handle or a
task_completion_handle, complementing the existing
functions that wait for the completion of all tasks in a group.
task_group::wait_for_task blocks until the task represented by the given task_completion_handle
has completed. Other tasks in the group may still be in progress when the function returns.
task_group::run_and_wait_for_task combines submitting a task for execution and waiting for its completion.
task_group::get_status_of returns the current status of the task without blocking.
If the completion of the awaited task was transferred to another task using
task_group::transfer_this_task_completion_to, all waiting functions track the task that received the completion
instead.
API#
Header#
#define TBB_PREVIEW_TASK_GROUP_EXTENSIONS 1
#include <oneapi/tbb/task_group.h>
#include <oneapi/tbb/task_arena.h>
Synopsis#
// <oneapi/tbb/task_group.h> synopsis
namespace oneapi {
namespace tbb {
enum task_group_status {
not_complete,
complete,
canceled,
task_complete
};
class task_group {
public:
task_group_status wait_for_task(task_completion_handle& comp_handle);
task_group_status run_and_wait_for_task(task_handle&& handle);
task_group_status get_status_of(task_completion_handle& comp_handle);
}; // class task_group
} // namespace tbb
} // namespace oneapi
// <oneapi/tbb/task_arena.h> synopsis
namespace oneapi {
namespace tbb {
class task_arena {
public:
task_group_status wait_for(task_completion_handle& comp_handle);
}; // class task_arena
} // namespace tbb
} // namespace oneapi
task_group_status Enumeration#
not_complete
The work is not yet finished. The meaning depends on the context:
When returned by
get_status_of: the individual task has not yet completed.When returned by
waitorrun_and_wait: not all tasks in the group have completed.
complete
The group was not canceled and all tasks in the group have completed.
canceled
The cancellation request has been received. The meaning depends on the context:
When returned by
get_status_ofor by a single-task waiting function: the individual task was not executed.When returned by
waitorrun_and_wait: group execution was canceled, the completion status of individual tasks is unknown.
task_complete
The individual task has completed execution. The cancellation status of the task_group is unknown - the individual task may be executed
even if the group received a cancellation request.
Member Functions of task_group Class#
task_group_status wait_for_task(task_completion_handle& comp_handle);
Waits for the completion of the task represented by comp_handle.
If completion was transferred to another task using task_group::transfer_this_task_completion_to,
the function waits for the task that received the completion.
Returns: task_group_status::task_complete if the task was executed, task_group_status::canceled otherwise.
task_group_status run_and_wait_for_task(task_handle&& handle);
Schedules the task represented by handle for execution (if it has no unresolved dependencies),
and waits for its completion.
If completion was transferred to another task using task_group::transfer_this_task_completion_to,
the function waits for the task that received the completion.
Semantically equivalent to task_completion_handle ch = handle; run(std::move(handle)); wait_for_task(ch);.
Returns: task_group_status::task_complete if the task was executed, task_group_status::canceled otherwise.
task_group_status get_status_of(task_completion_handle& comp_handle);
Returns: the status of the task represented by comp_handle:
task_group_status::not_complete- if the task has not been submitted for execution, or has not finished execution.task_group_status::task_complete- if the task has finished execution.task_group_status::canceled- if the task was not executed due totask_groupcancellation.
If the completion was transferred to another task using task_group::transfer_this_task_completion_to,
the function returns the status of the task that received the completion.
Member Functions of task_arena Class#
task_group_status wait_for(task_completion_handle& comp_handle);
Waits for completion of the task represented by comp_handle in the current arena.
If completion was transferred to another task using task_group::transfer_this_task_completion_to,
the function waits for the task that received the completion.
Semantically equivalent to: execute([&] { tg.wait_for_task(comp_handle); });, where
tg is a task_group where the task referred to by comp_handle is registered.
Returns: task_group_status::task_complete if the task was executed, task_group_status::canceled otherwise.
Example#
The example below demonstrates a cache-backed computation. The calculate_one_result
function checks a cache for a previously computed result. On a cache miss, it uses
run_and_wait_for_task to compute the result and return it to the caller immediately,
while the cache update runs asynchronously in the same task_group.
After all results are computed, tg.wait() ensures that every background cache store
has completed before the cache is cleared.
#define TBB_PREVIEW_TASK_GROUP_EXTENSIONS 1
#include <oneapi/tbb/task_group.h>
int calculate_one_result(tbb::task_group& tg, int input) {
int result = 0;
// Check cache first
if (cache_lookup(input, result)) {
return result;
}
// No cached item - run result calculation
// May build task graph with dependencies
tbb::task_handle calculate_task = tg.defer(calculate_result(input, result));
tg.run_and_wait_for_task(std::move(calculate_task));
// Result is calculated - run asynchronous caching
tg.run(cache_result(input, result));
// Return the result to caller
return result;
}
void calculate_all_results(const std::vector<int>& inputs, std::vector<int>& results) {
tbb::task_group tg;
for (std::size_t i = 0; i < inputs.size(); ++i) {
results[i] = calculate_one_result(tg, inputs[i]);
}
// Wait for all incomplete caching tasks before clear
tg.wait();
clear_cache();
}