TBB流程图:如何从输出中等待特定令牌?

时间:2013-07-26 11:28:29

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

我正在尝试为Flow Graph编写一个模拟类似管道的同步函数调用的适配器。但我不明白如何阻止和等待特定令牌的输出。在图表上调用wait_for_all没有帮助,因为我不需要等待所有值。有人可以提出解决方案吗?

template <typename TOutput, typename TInput>
class FlowPathAdapter {
public:
    TOutput operator()(const TInput& val) {
        m_input->try_put(val);
        TOutput result;
        // What should be done here to ensure that
        // m_output returns the result corresponding to this specific token?
        m_output->try_get(result);
        return result;
    }

private:
    // input and output are connected in some graph constructed outside the adapter
    std::shared_ptr<tbb::flow::receiver<TInput>> m_input;
    std::shared_ptr<tbb::flow::sender<TOutput>> m_output;
};

2 个答案:

答案 0 :(得分:0)

接收者和发送者类是“纯虚拟”类(try_ *方法有默认行为来简化节点的定义。)对于每个flow :: graph节点,它们被特定的行为覆盖。类。

如果要创建特定类型的节点(或适配器),则应覆盖虚拟方法。但是,您可以使用function_node来执行您尝试使用此适配器执行的操作。您可以删除try_get和try_put调用(这是function_node行为的一部分。)

// notice TInput and TOutput are exchanged
template < typename TInput, typename TOutput >
class FlowPathAdapterBody {
public:
    TOutput operator()(const TInput& val) {
        // val has the value passed to us
        TOutput result;
        // computation turning val into result
        return result;
    }
};

tbb::flow::graph g;
// node is fully-parallel in this case
tbb::flow::function_node<int, int> fnode(g, tbb::flow::unlimited, FlowPathAdapterBody<int,int>());

// ...

您可以将多个前置任务附加到function_node的输入,并将多个后继附加到其输出。

默认情况下,function_node在其输入上有一个缓冲区,因此即使节点是串行节点,它也总是接受输入。如果您希望拒绝输入而不是缓冲输入,则可以将节点设为function_node<T,U,tbb::flow::rejecting>.

如果您想要更高级的行为(例如每个输入发出多个消息的能力,或者可选择不为某些输入发送消息,或发出特殊条件信号,请查看multifunction_node。如果是多功能,则只能输出一个输出所需的一切。)

此致 克里斯

答案 1 :(得分:0)

TBB通常会避免等待;等待是非生产性的。

TBB中任务执行的时间也不能得到保证,因为我们依赖操作系统进行调度。也就是说,在转发来自节点的消息之后,不会发生诸如原子操作之类的带外信令,因此结果将不会准备好。您还必须使用queue_node或其他缓冲节点来保存结果。

鉴于此,如果您希望进行明确等待,您可以创建一个function_node来接收最终答案,将其分配到结果位置,然后发出信号告诉结果已准备就绪。 (信号应该是一个原子来强制执行防护。)你的另一个任务可以在原子上旋转等待。或者您可以使用条件变量。

此致 克里斯