2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-20 02:32:19 +00:00
Files
fiber/doc/future.qbk
Oliver Kowalke 49cb3692bd docu
2013-09-26 20:27:25 +02:00

89 lines
3.4 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]
[section:overview Overview]
The futures library provides a means of handling synchronous future values,
whether those values are generated by another thread, 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 non `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.
__async__ is a simple way of running asynchronous tasks. A call to __async__
returns a __future__ that will contain the result of the task.
[endsect]
[section:creating 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 that wraps a
function or callable object. When the packaged task is invoked, it invokes the
contained function in turn, and populates a future with the 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(boost::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 may come from more than one possible source, or where a
single operation may produce multiple values.
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);
[endsect]
[endsect]