I'm currently testing the flow graph feature of tbb. In order to use it, I must be able to abort execution of some node in the graph, including all children which depend on it but leave other children which do not depend on it, executing. Throwing an exception from the body or calling task::cancel_group_execution() aborts the execution of all nodes.
#include <cstdio>
#include "tbb/flow_graph.h"
using namespace tbb::flow;
struct body
{ std::string my_name;
body( const char *name ) : my_name(name)
{
}
void operator()( continue_msg ) const
{ if (my_name == "B")
tbb::task::self().group()->cancel_group_execution();
else
{ sleep(1);
printf("%s\n", my_name.c_str());
}
}
};
int main()
{
graph g;
broadcast_node< continue_msg > start(g);
continue_node<continue_msg> a( g, body("A"));
continue_node<continue_msg> b( g, body("B"));
continue_node<continue_msg> c( g, body("C"));
continue_node<continue_msg> d( g, body("D"));
continue_node<continue_msg> e( g, body("E"));
make_edge( start, a );
make_edge( start, b );
make_edge( a, c );
make_edge( b, c );
make_edge( c, d );
make_edge( a, e );
for (int i = 0; i < 3; ++i )
try
{ start.try_put( continue_msg() );
g.wait_for_all();
} catch (...)
{ printf("Caught exception\n");
}
return 0;
}
You can represent abort status with
bool
instead ofcontinue_msg
. Eachprocess_node
receive predecessor node status and process task when it's available, and send updated abort status to successor node.