如何解决_flow_graph_cache_impl.h 中的 tbb 流图分段错误
我正在尝试使用流图运行一些代码,它编译成功,但是在调用输入节点后运行它时会在 tbb 流图库文件中出现分段错误,我似乎无法找到它的原因。 我的输入节点是这样的:
class InputNode{
public:
// constructor,copy constructor,destructor are implemented
bool operator() (InputResult &v){
//some logic here that defines wether to process or not
if(shouldProcess){
v = InputResult();
// some logic to set values inside v
return true;
} else
return false;
}
};
该节点连接到类型为tbb::flow::multifunction_node<InputResult,std::tuple<InputResult>>
的节点,连接由tbb::flow::make_edge(src,firstNodeFilter);
完成。 InputResult 是一个指针,我已经检查并确认它被设置为一个不为空的有效值。
在 tbb::flow::interface11::internal::broadcast_cache
处的函数 try_put_task
在 task *new_task = (*i)->try_put_task(t);
中抛出异常,该函数由 tbb::flow::interface11::input_node
处的 apply_body_bypass
函数在 task *last_task = my_successors.try_put_task(v);
处调用>
-----------编辑------------
很抱歉关于 input_node 实现的不清楚。我已经为它实现了这段代码。
tbb::flow::input_node<InputResult> src(g,InputNode());
当我尝试更改 InputNode 以匹配 InputNodeBody 时,我在 _flow_graph_body_impl.h 中收到编译器错误:
error: no match for call to `InputResult&`
bool operator()((Output &output) __TBB_override {return body( output ); }
并说没有从 tbb::flowcontrol& 到 InputResult& 的已知转换
-------------编辑 2 ------------------------ 以下包括我的更多代码,删除了一些模板参数以提高可读性。此代码是在升级 oneTBB 之后。
文件 1:
class NavigationQueryExecuter {
public:
EdgesRepoClass &edges;
NodeRepoClass &nodes;
LinkageRepoClass &linkage;
NavigationQueryExecuter(NodeRepoClass& nodeRepo,EdgesRepoClass& edgeRepo,LinkageRepoClass& linkageRepo): nodes(nodeRepo),edges(edgeRepo),linkage(linkageRepo){ };
template<class TQuery>
TQuery* Execute(){
typedef typename TQuery::InputResult TInputResult;
auto query = new TQuery();
class InputNode{
private:
const unsigned int Count = 1024; //const count.
NodeRepoClass &nodes;
TQuery& query;
TPage* lastPage;
TPid pid;
const TPid lpid;
unsigned int idx;
public:
InputNode(TQuery&q,NodeRepoClass& nodeRepo,TPid firstPageId,TPid lastPageId): query(q),nodes(nodeRepo),lpid(lastPageId){
idx=0;
pid=firstPageId;
lastPage= nodes.GetPage(pid);
}
InputNode(const InputNode &other): query(other.query),nodes(other.nodes),pid(other.pid),lpid(other.lpid),idx(other.idx){
lastPage = nodes.GetPage(other.lastPage->Id);
}
~InputNode(){
if(lastPage){
nodes.ReleasePage(lastPage);
lastPage= nullptr;
}
}
TInputResult operator() (tbb::flow_control &fc){ //this function is invoked once only before exception is thrown.
//logic to skip unused objects removed for simplicity.
auto node = new NodeClass(lastPage,idx);
while(idx < Count){
if(node->InUse()){
auto res = query.ProcessInput(node);
delete node;
return res; //res is set correctly,breaks after returning without touching any other parts of my code.
}
node->Id = ++idx;
}
delete node;
fc.stop();
return nullptr;
}
};
auto g = tbb::flow::graph();
tbb::flow::input_node<TInputResult> src(g,InputNode(*query,nodes,40));
query->BuildGraph(g,src);
src.activate();
g.wait_for_all();
return query;
}
};
文件 2:
class QueryExample{
EdgesRepoClass &edges;
NodeRepoClass &nodes;
LinkageRepoClass &linkage;
public:
struct Result{
int n1,n2,e1;
};
typedef Result* InputResult;
typedef std::vector<InputResult> OutputResult;
typedef tbb::flow::multifunction_node<InputResult,std::tuple<InputResult>> FilterNodeType;
OutputResult result;
FilterOnNode(NodeRepoClass& nodeRepo,linkage(linkageRepo){
result=OutputResult();
}
InputResult ProcessInput(typename NodeRepoClass::TEntry* node){
//initialize,and process all nodes.
Result* res = new Result();
res->n1 = node->Id;
return res;
}
void BuildGraph(tbb::flow::graph &g,tbb::flow::input_node<InputResult> &src) {
auto firstNodeFilter = FilterNodeType(
g,tbb::flow::unlimited,[&](const InputResult &input,typename FilterNodeType::output_ports_type &op) {
//processing logic can either output to connected nodes or drop unncessary nodes.
//this function is never reached,code breaks before it.
});
// couple more multifunction_node are created.
tbb::flow::make_edge(src,firstNodeFilter);
tbb::flow::make_edge(tbb::flow::output_port<0>(firstNodeFilter),generateEdgesFilter);
tbb::flow::make_edge(tbb::flow::output_port<0>(generateEdgesFilter),secondNodeFilter);
tbb::flow::make_edge(tbb::flow::output_port<0>(secondNodeFilter),outputNodeFilter);
}
};
解决方法
输入节点(前源节点)的接口与通过引用填充的传递消息存在缺陷,导致可能在输入节点及其后继节点中同时使用相同的内存位置。考虑朝这个方向寻找分段错误的根本原因。
另外,考虑使用新的接口,它基于 tbb::flow_control 并从节点主体返回生成的消息:input_node,其 body requirements
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。