]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/ |
2 | Copyright Oliver Kowalke 2013. | |
3 | Distributed under the Boost Software License, Version 1.0. | |
4 | (See accompanying file LICENSE_1_0.txt or copy at | |
5 | http://www.boost.org/LICENSE_1_0.txt | |
6 | ] | |
7 | ||
8 | [section:futures Futures] | |
9 | ||
10 | [heading Overview] | |
11 | ||
12 | The futures library provides a means of handling asynchronous future values, | |
13 | whether those values are generated by another fiber, or on a single fiber in | |
14 | response to external stimuli, or on-demand. | |
15 | ||
16 | This is done through the provision of four class templates: __future__ and | |
17 | __shared_future__ which are used to retrieve the asynchronous results, and | |
18 | __promise__ and __packaged_task__ which are used to generate the asynchronous | |
19 | results. | |
20 | ||
21 | An instance of __future__ holds the one and only reference to a result. | |
22 | Ownership can be transferred between instances using the move constructor or | |
23 | move-assignment operator, but at most one instance holds a reference to a given | |
24 | asynchronous result. When the result is ready, it is returned from | |
25 | __future_get__ by rvalue-reference to allow the result to be moved or copied as | |
26 | appropriate for the type. | |
27 | ||
28 | On the other hand, many instances of __shared_future__ may reference the same | |
29 | result. Instances can be freely copied and assigned, and __shared_future_get__ | |
30 | returns a `const` reference so that multiple calls to __shared_future_get__ | |
31 | are safe. You can move an instance of __future__ into an instance of | |
32 | __shared_future__, thus transferring ownership of the associated asynchronous | |
33 | result, but not vice-versa. | |
34 | ||
35 | [ns_function_link fibers..async] is a simple way of running asynchronous | |
36 | tasks. A call to __async__ spawns a fiber and returns a __future__ that will | |
37 | deliver the result of the fiber function. | |
38 | ||
39 | ||
40 | [heading Creating asynchronous values] | |
41 | ||
42 | You can set the value in a future with either a __promise__ or a | |
43 | __packaged_task__. A __packaged_task__ is a callable object with `void` return | |
44 | that wraps a function or callable object returning the specified type. When | |
45 | the __packaged_task__ is invoked, it invokes the contained function in turn, and | |
46 | populates a future with the contained function's return value. This is an | |
47 | answer to the perennial question: ["How do I return a value from a fiber?] | |
48 | Package the function you wish to run as a __packaged_task__ and pass the | |
49 | packaged task to the fiber constructor. The future retrieved from the packaged | |
50 | task can then be used to obtain the return value. If the function throws an | |
51 | exception, that is stored in the future in place of the return value. | |
52 | ||
53 | int calculate_the_answer_to_life_the_universe_and_everything() { | |
54 | return 42; | |
55 | } | |
56 | ||
57 | boost::fibers::packaged_task<int()> pt(calculate_the_answer_to_life_the_universe_and_everything); | |
58 | boost::fibers::future<int> fi=pt.get_future(); | |
59 | boost::fibers::fiber(std::move(pt)).detach(); // launch task on a fiber | |
60 | ||
61 | fi.wait(); // wait for it to finish | |
62 | ||
63 | assert(fi.is_ready()); | |
64 | assert(fi.has_value()); | |
65 | assert(!fi.has_exception()); | |
66 | assert(fi.get()==42); | |
67 | ||
68 | A __promise__ is a bit more low level: it just provides explicit functions to | |
69 | store a value or an exception in the associated future. A promise can therefore | |
70 | be used where the value might come from more than one possible source. | |
71 | ||
72 | boost::fibers::promise<int> pi; | |
73 | boost::fibers::future<int> fi; | |
74 | fi=pi.get_future(); | |
75 | ||
76 | pi.set_value(42); | |
77 | ||
78 | assert(fi.is_ready()); | |
79 | assert(fi.has_value()); | |
80 | assert(!fi.has_exception()); | |
81 | assert(fi.get()==42); | |
82 | ||
83 | ||
84 | [include future.qbk] | |
85 | [include promise.qbk] | |
86 | [include packaged_task.qbk] | |
87 | ||
88 | [endsect] |