主线程以后可以加入TBB竞技场群吗?

Can master thread later join the TBB arena group?

比如说,有一个主线程部署 TBB 以产生额外的工作线程,如下面的代码片段所示。

主线程继续其业务,无需等待竞技场组完成。但是,主线程可能恰好在工作线程之前完成。

所以合乎逻辑的问题是:是否可以将主线程延迟加入竞技场组并使用它的时钟来帮助完成剩余的工作?是否有任何等效的基于 TBB 的解决方案来实现这种情况?

tbb::task_group group;
tbb::task_arena arena(nthreads, 1);

tbb::task_scheduler_init init(nthreads);

arena.enqueue( [&]
{
    group.run( [&]
    {
        ...
    });
});

// Work done on master thread here

// Master thread has finished: can it now join the arena group
// and help with the remaining work?

group.wait();

单独使用 task_arena 无法做到这一点,但 task_arenatask_group 的组合会起作用。你的代码几乎是正确的,除了你需要

  • 在竞技场内呼叫group.wait()
  • 使用 arena.execute() 而不是 enqueue() 这样 group.run() 肯定会在 group.wait().
  • 之前被调用

这里是固定样本(TBB documentation for task_arena也有类似的样本):

tbb::task_group group;
tbb::task_arena arena(nthreads, 1);

tbb::task_scheduler_init init(nthreads);

arena.execute( [&]
{
    group.run( [&]
    {
        ...
    });
});

// Work done on master thread here

// Master thread has finished; now it joins the arena group
// and helps with the remaining work
arena.execute( [&]
{
    group.wait();
});

它可能看起来有点 over-complicated,但如果您认为 task_arena 是工人的抽象,而不是工作的抽象,它就开始有意义了。我们想添加一个 task_arena::wait() 方法,但发现它在语义上是不明确的("no free tasks left" 并不意味着 "work is done"),并且如果被已经在该区域中的线程意外调用可能会死锁。与 task_group 的组合由于等待特定的任务组而不是 "all submitted work".

而没有这两个缺点