独立子任务执行

Independed Child Task Execution

本文关键字:执行 子任务 独立      更新时间:2023-10-16

我是第一次使用TBB,想要运行一系列完全独立的任务。我想使用 tbb::task::enqueue,即我创建一个根任务,它创建一个独立于父任务的子任务。这个孩子可以再次创建任务,依此类推。

我的解决方案不起作用,因为子任务再次调用父任务,并且我得到了无休止的级联。根任务的执行有效,但是一旦创建了子任务,就会有无休止的级联。


// initialization
tbb::task::enqueue( *new( tbb::task::allocate_root() ) tbbwrapper::ctask( <some data> ) );
// execute method
tbb::task* ctask::execute()
{
    <execute data processing>
    return <data result correct> 
    ? new( this->allocate_child() ) tbbwrapper::ctask( <result data> ) 
    : NULL;
}

我有很多任务(都是独立的,执行顺序也是完全独立的(要运行,每个任务都可以创建一个后继任务,但它完全不依赖,只需要添加到队列中即可运行。我也不需要等待或类似的东西,因为执行应该在后台运行。

我只需要一个简单的例子来告诉我它是如何工作的。

通常不建议直接使用 TBB 任务 API,因为它过于复杂,并且包含很多隐藏问题。如果您事先知道任务的数量,则可能需要使用 tbb::parallel_for .如果要在算法执行过程中添加任务,可以使用tbb::parallel_do feeder功能。如果您不想使用算法并想操作任务,请考虑使用 tbb::task_group .

即使应用程序结束,您也不需要等待后台工作完成吗?您可以使用tbb::task_group创建后台任务,例如

tbb::task_group tg;
// Run parallel_for in background.
tg.run( [] { 
    tbb::parallel_for(...);
} );
// ...
// Any other code
// ...
tg.wait(); // task_group requires to call `wait` to guarantee that all tasks are really processed

如果要保证后台工作的并发执行,则可以将唯一一个将使用其他 TBB 算法创建额外工作的任务排队。

[更新]

考虑在后台运行函数的run_task帮助程序。

#include "tbb/task.h"
#include <iostream>
#include <thread>
template <typename F>
class task_wrapper : public tbb::task {
    F f_;
public:
    task_wrapper(F f) : f_(f) {}
    tbb::task* execute() override {
        f_();
        return NULL;
    }
};
template <typename F>
void run_task(F f) {
    tbb::task::enqueue(*new(tbb::task::allocate_root()) task_wrapper<F>(f));
}
int main() {
    for (int i = 0; i < 10; ++i) {
        run_task([i] {
            std::cout << i << std::endl;
        });
    }
    // Give time to proceed the background tasks.
    using namespace std::chrono_literals;
    std::this_thread::sleep_for(1s);
    return 0;
}