![]() |
This method is very similar to the method described in section Applying
an Action Asynchronously with Synchronization. In addition to
what hpx::async
can do, the functions hpx::async_continue
takes an additional
function argument. This function will be called as the continuation of
the executed action. It is expected to perform additional operations
and to make sure that a result is returned to the original invocation
site. This method chains operations asynchronously by providing a continuation
operation which is automatically executed once the first action has finished
executing.
As an example we chain two actions, where the result of the first action is forwarded to the second action and the result of the second action is sent back to the original invocation site:
// first action boost::int32_t action1(boost::int32_t i) { return i+1; } HPX_PLAIN_ACTION(action1); // defines action1_type // second action boost::int32_t action2(boost::int32_t i) { return i*2; } HPX_PLAIN_ACTION(action2); // defines action2_type // this code invokes 'action1' above and passes along a continuation // function which will forward the result returned from 'action1' to // 'action2'. action1_type act1; // define an instance of 'action1_type' action2_type act2; // define an instance of 'action2_type' hpx::future<int> f = hpx::async_continue(act1, hpx::find_here(), 42, hpx::make_continuation(act2)); hpx::cout << f.get() << "\n"; // will print: 86 ((42 + 1) * 2)
By default, the continuation is executed on the same locality as hpx::async_continue
is invoked from. If
you want to specify the locality where the continuation should be executed,
the code above has to be written as:
// this code invokes 'action1' above and passes along a continuation // function which will forward the result returned from 'action1' to // 'action2'. action1_type act1; // define an instance of 'action1_type' action2_type act2; // define an instance of 'action2_type' hpx::future<int> f = hpx::async_continue(act1, hpx::find_here(), 42, hpx::make_continuation(act2, hpx::find_here())); hpx::cout << f.get() << "\n"; // will print: 86 ((42 + 1) * 2)
Similarily, it is possible to chain more than 2 operations:
action1_type act1; // define an instance of 'action1_type' action2_type act2; // define an instance of 'action2_type' hpx::future<int> f = hpx::async_continue(act1, hpx::find_here(), 42, hpx::make_continuation(act2, hpx::make_continuation(act1))); hpx::cout << f.get() << "\n"; // will print: 87 ((42 + 1) * 2 + 1)
The function hpx::make_continuation
creates a special
function object which exposes the following prototype:
struct continuation { template <typename Result> void operator()(hpx::id_type id, Result&& result) const { ... } };
where the parameters passed to the overloaded function operator (operator()()
)
are:
id
is the global
id where the final result of the asynchronous chain of operations
should be sent to (in most cases this is the id of the hpx::future
returned from the initial
call to hpx::async_continue
). Any custom continuation
function should make sure this id
is forwarded to the last operation in the chain.
result
is the
result value of the current operation in the asynchronous execution
chain. This value needs to be forwarded to the next operation.
![]() |
Note |
---|---|
All of those operations are implemented by the predefined continuation
function object which is returned from |