[英]TBB task allocation assertion
我试图通过TBB任务和延续遍历一棵树。 代码如下。 当我运行代码时,它会不断中止(尽管并非总是如此),但经常出现以下错误:
断言t_next-> state()== task :: allocation在文件../../src/tbb/custom_scheduler.h的第334行失败。详细说明:如果task :: execute()返回task,则必须将其标记为已分配
是什么导致此问题?
template<class NodeVisitor>
void
traverse_tree(NodeVisitor& nv)
{
TreeTraversal<NodeVisitor>& tt = *(new(task::allocate_root()) TreeTraversal<NodeVisitor>(nv));
task::spawn_root_and_wait(tt);
}
template<class NodeVisitor>
class TreeTraversal: public task
{
public:
struct Continuation;
public:
TreeTraversal(NodeVisitor nv_):
nv(nv_) {}
task* execute()
{
nv.pre();
Continuation* c = new(allocate_continuation()) Continuation(nv);
c->set_ref_count(nv.size());
for (size_t i = 0; i < nv.size(); ++i)
{
TreeTraversal& tt = *(new(c->allocate_child()) TreeTraversal(nv.child(i)));
spawn(tt);
}
if (!nv.size())
return c;
return NULL;
}
private:
NodeVisitor nv;
};
template<class NodeVisitor>
class TreeTraversal<NodeVisitor>::Continuation: public task
{
public:
Continuation(NodeVisitor& nv_):
nv(nv_) {}
task* execute() { nv.post(); return NULL; }
private:
NodeVisitor nv;
};
我从未见过将任务分配为延续,然后从execute()
返回。 这可能是断言失败的原因( 更新 :实验表明不是,请参见下面的详细信息)。
同时,您可以将TreeTraversal::execute()
的代码大致更改为:
nv.pre();
if (!nv.size())
nv.post();
else {
// Do all the task manipulations
}
return NULL;
更新 :下面显示的简化测试在我的双核笔记本电脑上运行良好。 这使我假设您的实际代码中可能存在内存损坏,在这种情况下,上面建议的重新改组可能只会隐藏问题,而无法解决。
#include "tbb/task.h"
using namespace tbb;
class T: public task {
public:
class Continuation: public task {
public:
Continuation() {}
task* execute() { return NULL; }
};
private:
size_t nv;
public:
T(size_t n): nv(n) {}
task* execute() {
Continuation* c = new(allocate_continuation()) Continuation();
c->set_ref_count(nv);
for (size_t i = 0; i < nv; ++i) {
T& tt = *(new(c->allocate_child()) T(nv-i-1));
spawn(tt);
}
return (nv==0)? c : NULL;
}
};
int main() {
T& t = *new( task::allocate_root() ) T(24);
task::spawn_root_and_wait(t);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.