微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

_flow_graph_cache_impl.h 中的 tbb 流图分段错误

如何解决_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_tasktask *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);

    }
};

代码在注释中文件 1 中指示的位置中断。

解决方法

输入节点(前源节点)的接口与通过引用填充的传递消息存在缺陷,导致可能在输入节点及其后继节点中同时使用相同的内存位置。考虑朝这个方向寻找分段错误的根本原因。

另外,考虑使用新的接口,它基于 tbb::flow_control 并从节点主体返回生成的消息:input_node,其 body requirements

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?