【问题标题】:TBB flow graph conditional executionTBB 流程图条件执行
【发布时间】:2013-07-23 19:15:13
【问题描述】:

是否可以动态控制TBB Flow Graph中的执行路径,使用一个节点的输出作为条件变量来确定是否应该启动另一个节点?

【问题讨论】:

    标签: c++ multithreading asynchronous tbb tbb-flow-graph


    【解决方案1】:

    有几种方法可以动态控制消息在流中的位置::graph:

    您可以在节点主体中显式地将消息发送到其他节点。请注意,func_body 将消息发送到f1f2,具体取决于其输入的值。节点不是由make_edge() 附加的,因为消息流不受图的拓扑控制:

    template<typename T>
    struct func_body {
        typedef tbb::flow::function_node<T,T> target_node_type;
        target_node_type &my_n1;
        target_node_type &my_n2;
        func_body(target_node_type &node1, target_node_type &node2) : my_n1(node1), my_n2(node2) {}
        tbb::flow::continue_msg operator()(const T& in) {
            // do some computation
            bool send_to_one = in > 0;
            if(send_to_one) my_n1.try_put(in);
            else            my_n2.try_put(in);
            return tbb::flow::continue_msg();  // message is discarded if no successor exists
        }
    };
    
    struct otherbody {
        int operator()(const int& in) {
            return in;
        }
    };
    
    int
    main() {
        tbb::flow::graph g;
        tbb::flow::function_node<int,int> f1(g, tbb::flow::unlimited, otherbody());
        tbb::flow::function_node<int,int> f2(g, tbb::flow::unlimited, otherbody());
        tbb::flow::function_node<int> cn(g, tbb::flow::unlimited, func_body<int>(f1,f2));
    }
    

    或者您可以使用multifunction_node(注意tupleget 模板的类型位于tbb::flow 命名空间中,而不是旧文档中的std::。)请注意,在这种情况下,我们附上f1f2multifunction_node的输出端口。

    typedef tbb::flow::multifunction_node<int,tbb::flow::tuple<int,int> > mfnode;
    
    struct mfunc_body {
        void operator()(const int& in, mfnode::output_ports_type &op) {
            // do some computation
            bool send_to_one = in > 0;
            if(send_to_one) tbb::flow::get<0>(op).try_put(in);
            else            tbb::flow::get<1>(op).try_put(in);
        }
    };
    
    struct otherbody {
        int operator()(const int& in) {
            return in;
        }
    };
    
    int
    main() {
        tbb::flow::graph g;
        tbb::flow::function_node<int,int> f1(g, tbb::flow::unlimited, otherbody());
        tbb::flow::function_node<int,int> f2(g, tbb::flow::unlimited, otherbody());
        mfnode cn(g, tbb::flow::unlimited, mfunc_body());
        tbb::flow::make_edge(tbb::flow::output_port<0>(cn), f1);
        tbb::flow::make_edge(tbb::flow::output_port<1>(cn), f2);
    
        // ...
    }
    

    目前这两种方法在功能上是相同的;每个都会产生一个任务来执行function_nodes 的主体。将来multifunction_node 的情况可能会优化为如果只有一个输出端口是try_put() 时不会生成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      • 2019-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多