struct root: public task
{
root(){}
tbb::task* execute(){
tbb::task_list l;
tbb::task& c = *new(allocate_continuation()) tbb::empty_task;
int count=0;
// do what this task should do
while(condition){
l.push_back(*new(c.allocate_child())root());
++count;
}
if(count){
c.set_ref_count(count);
c.spawn(l);
}
return NULL;
}
};
main(){
tbb::task_scheduler_init s();
root& r = *new(tbb::task::allocate_root())root();
tbb::task::spawn_root_and_wait(r);
return 0;
}
嗨,我已经定义了一个TBB任务"root“,它可以完成一些工作,如果满足condition
循环中的while
,则会进一步递归。如果count==0
在while
循环之后(这意味着不需要进一步递归),那么我将不会生成更多的任务。
因为root
任务所做的事情不需要继续更新,所以我使用tbb::empty_task
作为延续任务。
问题是这样做会阻止执行。程序不能正常返回。就目前而言,我的解决办法是:
if(!count){
l.push_back(*new(c.allocate_child())tbb::empty_task);
c.spawn(l);
c.set_ref_count(1);
}
然而,我认为价格是表现。我想知道为什么原始代码不能工作。它在另一种情况下工作,在这种情况下,延续任务不是空任务。我不太明白里面的逻辑。谢谢你的评论。
发布于 2015-02-06 18:07:59
一个问题是,当count==0
时,任务c
会丢失,因为它没有子任务,也没有生成子任务。释放任务的正确方法是调用tbb::task::destroy
。但是,由于您将它作为一个延续分配,将向spawn_root_and_wait
发送信号的责任转移到任务c
。由于任务丢失,信号也会丢失,从而导致您所观察到的死锁。要有效地完成count==0
情况下的信令,只需返回指向此c
任务的指针,因为root::execute()
与执行spawn(c)
类似,但避免了同步的额外开销。
另一种方法是执行c.parent()->decrement_ref_count()
并手动调用destroy(c)
。
https://stackoverflow.com/questions/28370444
复制相似问题