Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ TBB任务在不再递归时被阻止_C++_Tbb - Fatal编程技术网

C++ TBB任务在不再递归时被阻止

C++ TBB任务在不再递归时被阻止,c++,tbb,C++,Tbb,您好,我已经定义了一个TBB任务“root”,它执行一些工作,然后在满足中的条件时进一步递归。如果count==0在while循环之后,这意味着不需要进一步的递归,那么我将不会生成更多的任务 因为root任务所做的不需要继续更新,所以我使用tbb::empty_task作为继续任务 问题是这样做会阻碍执行。程序无法正常返回。目前,我的解决方案是: struct root: public task { root(){} tbb::task* execute(){ tbb::task_li

您好,我已经定义了一个TBB任务“root”,它执行一些工作,然后在满足
中的
条件
时进一步递归。如果
count==0
while
循环之后,这意味着不需要进一步的递归,那么我将不会生成更多的任务

因为
root
任务所做的不需要继续更新,所以我使用
tbb::empty_task
作为继续任务

问题是这样做会阻碍执行。程序无法正常返回。目前,我的解决方案是:

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;
}

然而,我认为价格就是性能。我想知道为什么原始代码不起作用。它在另一种情况下工作,即延续任务不是空任务。我不太明白其中的逻辑。谢谢你的评论

一个问题是,当
count==0
时,任务
c
会丢失,因为它没有子任务,也没有生成。取消分配任务的正确方法是调用。但是,由于您将其分配为一个延续,向
spawn\u root\u和
发出工作已完成的信号的责任转移到任务
c
。由于任务丢失了,信号也丢失了,这导致了您观察到的死锁。为了有效地为
count==0
案例发送信号,只需返回指向此
c
任务的指针,作为
root::execute()
的结果,这与执行
spawn(c)
类似,但避免了额外的同步开销


另一种方法是手动执行
c.parent()->decrement\u ref\u count()
并调用
destroy(c)

谢谢。当我在
count==0时返回continuation task的指针时,它就工作了。但是,如果我改为
c.parent()->decrement\u ref\u count()
task::destroy(c)
,它会再次阻塞。我认为这是因为继续任务在销毁之前还没有生成。@Alex,你是否只在
count==0
的情况下进行减量和销毁?任务可以生成也可以销毁,因为生成的任务会自动销毁。奇怪的是,它仍然阻塞
if(!count){
  l.push_back(*new(c.allocate_child())tbb::empty_task);
  c.spawn(l);
  c.set_ref_count(1);
}