Intel® oneAPI Threading Building Blocks Developer Guide and API Reference
sequencer_node
[flow_graph.sequencer_node]
A node that forwards messages in a sequence order.
// Defined in header <oneapi/tbb/flow_graph.h>
namespace oneapi {
namespace tbb {
namespace flow {
template< typename T >
class sequencer_node : public graph_node, public receiver<T>, public sender<T> {
public:
template< typename Sequencer >
sequencer_node( graph &g, const Sequencer &s );
sequencer_node( const sequencer_node &src );
// Preview feature: Helper Functions for Expressing Graphs
template< typename Sequencer >
sequencer_node(decltype(follows(...)), const Sequencer& s);
template< typename Sequencer >
sequencer_node(decltype(precedes(...)), const Sequencer& s);
bool try_put( const T &v );
bool try_get( output_type &v );
// Preview feature: Waiting for Single Message
bool try_put_and_wait( const T &v );
};
} // namespace flow
} // namespace tbb
} // namespace oneapi
Requirements:
The type T must meet the CopyConstructible requirements from [copyconstructible] and CopyAssignable requirements from [copyassignable] ISO C++ Standard sections.
The type Sequencer must meet the Sequencer requirements. Since C++17, Sequencer may also be a pointer to a const member function in T that returns size_t or a pointer to a data member in T of type size_t. If Sequencer instance throws an exception, behavior is undefined.
sequencer_node forwards messages in a sequence order to a single successor in its successor set.
sequencer_node is a graph_node, receiver<T> and sender<T>.
Each item that passes through a sequencer_node is ordered by its sequencer order number. These sequence order numbers range from 0 to the largest integer representable by the std::size_t type. Sequencer order number of an item is determined by passing the item to a user-provided Sequencer function object.
Member functions
template<typenameSequencer>sequencer_node(graph&g, constSequencer&s)
Constructs an empty sequencer_node that belongs to the graph g and uses s to compute sequence numbers for items.
sequencer_node(constsequencer_node&src)
Constructs an empty sequencer_node that belongs to the same graph g as src and uses a copy of the Sequencer s used to construct src. The list of predecessors, the list of successors, and the messages inside are not copied.
booltry_put(constT&v)
Adds v to the sequencer_node and tries forwarding the next item in the sequence to a successor.
Returns: true
booltry_get(T&v)
Returns: true if the next item in the sequence is available in the sequencer_node. If so, it is removed from the node and assigned to v. Returns false if the next item in sequencer order is not available or if the node is reserved.
Deduction Guides
template <typename Body>
sequencer_node(graph&, Body) -> input_node<std::decay_t<input_t<Body>>>;
Where:
input_t is an alias to Body input argument type.
Preview Features
The following preview features extend the sequencer_node API:
Helper Functions for Expressing Graphs - allows sequencer_node to be constructed as a successor or a predecessor of the set of nodes.
Waiting for Single Message in Flow Graph - allows to put messages to sequencer_node and wait for all related work to complete.
Example
The example demonstrates ordering capabilities of the sequencer_node. While being processed in parallel, the data is passed to the successor node in the exact same order it was read.
#include "oneapi/tbb/flow_graph.h"
struct Message {
int id;
int data;
};
int main() {
oneapi::tbb::flow::graph g;
// Due to parallelism the node can push messages to its successors in any order
oneapi::tbb::flow::function_node< Message, Message > process(g, oneapi::tbb::flow::unlimited, [] (Message msg) -> Message {
msg.data++;
return msg;
});
oneapi::tbb::flow::sequencer_node< Message > ordering(g, [](const Message& msg) -> int {
return msg.id;
});
oneapi::tbb::flow::function_node< Message > writer(g, oneapi::tbb::flow::serial, [] (const Message& msg) {
printf("Message received with id: %d\n", msg.id);
});
oneapi::tbb::flow::make_edge(process, ordering);
oneapi::tbb::flow::make_edge(ordering, writer);
for (int i = 0; i < 100; ++i) {
Message msg = { i, 0 };
process.try_put(msg);
}
g.wait_for_all();
}