我正在尝试使用流程图运行一些代码,它编译成功,但是在运行时它在调用输入节点后在 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& 没有已知的演员表
-------------edit 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, 0, 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, EdgesRepoClass& edgeRepo, LinkageRepoClass& linkageRepo): nodes(nodeRepo),edges(edgeRepo), 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);
}
};
代码在注释中文件 1 中指示的位置中断。