12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- [/
- 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]
|