89 lines
3.5 KiB
Plaintext
89 lines
3.5 KiB
Plaintext
[/
|
|
Copyright Oliver Kowalke 2013.
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file LICENSE_1_0.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt
|
|
]
|
|
|
|
[section:futures Futures]
|
|
|
|
[heading Overview]
|
|
|
|
The futures library provides a means of handling asynchronous future values,
|
|
whether those values are generated by another fiber, or on a single fiber in
|
|
response to external stimuli, or on-demand.
|
|
|
|
This is done through the provision of four class templates: __future__ and
|
|
__shared_future__ which are used to retrieve the asynchronous results, and
|
|
__promise__ and __packaged_task__ which are used to generate the asynchronous
|
|
results.
|
|
|
|
An instance of __future__ holds the one and only reference to a result.
|
|
Ownership can be transferred between instances using the move constructor or
|
|
move-assignment operator, but at most one instance holds a reference to a given
|
|
asynchronous result. When the result is ready, it is returned from
|
|
__future_get__ by rvalue-reference to allow the result to be moved or copied as
|
|
appropriate for the type.
|
|
|
|
On the other hand, many instances of __shared_future__ may reference the same
|
|
result. Instances can be freely copied and assigned, and __shared_future_get__
|
|
returns a `const` reference so that multiple calls to __shared_future_get__
|
|
are safe. You can move an instance of __future__ into an instance of
|
|
__shared_future__, thus transferring ownership of the associated asynchronous
|
|
result, but not vice-versa.
|
|
|
|
[ns_function_link fibers..async] is a simple way of running asynchronous
|
|
tasks. A call to __async__ spawns a fiber and returns a __future__ that will
|
|
deliver the result of the fiber function.
|
|
|
|
|
|
[heading Creating asynchronous values]
|
|
|
|
You can set the value in a future with either a __promise__ or a
|
|
__packaged_task__. A __packaged_task__ is a callable object with `void` return
|
|
that wraps a function or callable object returning the specified type. When
|
|
the __packaged_task__ is invoked, it invokes the contained function in turn, and
|
|
populates a future with the contained function's return value. This is an
|
|
answer to the perennial question: ["How do I return a value from a fiber?]
|
|
Package the function you wish to run as a __packaged_task__ and pass the
|
|
packaged task to the fiber constructor. The future retrieved from the packaged
|
|
task can then be used to obtain the return value. If the function throws an
|
|
exception, that is stored in the future in place of the return value.
|
|
|
|
int calculate_the_answer_to_life_the_universe_and_everything() {
|
|
return 42;
|
|
}
|
|
|
|
boost::fibers::packaged_task<int()> pt(calculate_the_answer_to_life_the_universe_and_everything);
|
|
boost::fibers::future<int> fi=pt.get_future();
|
|
boost::fibers::fiber(std::move(pt)).detach(); // launch task on a fiber
|
|
|
|
fi.wait(); // wait for it to finish
|
|
|
|
assert(fi.is_ready());
|
|
assert(fi.has_value());
|
|
assert(!fi.has_exception());
|
|
assert(fi.get()==42);
|
|
|
|
A __promise__ is a bit more low level: it just provides explicit functions to
|
|
store a value or an exception in the associated future. A promise can therefore
|
|
be used where the value might come from more than one possible source.
|
|
|
|
boost::fibers::promise<int> pi;
|
|
boost::fibers::future<int> fi;
|
|
fi=pi.get_future();
|
|
|
|
pi.set_value(42);
|
|
|
|
assert(fi.is_ready());
|
|
assert(fi.has_value());
|
|
assert(!fi.has_exception());
|
|
assert(fi.get()==42);
|
|
|
|
|
|
[include future.qbk]
|
|
[include promise.qbk]
|
|
[include packaged_task.qbk]
|
|
|
|
[endsect]
|