2 (C) Copyright 2008-11 Anthony Williams.
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).
8 [section:futures Futures]
10 [template future_state_link[link_text] [link thread.synchronization.futures.reference.future_state [link_text]]]
11 [def __uninitialized__ [future_state_link `boost::future_state::uninitialized`]]
12 [def __ready__ [future_state_link `boost::future_state::ready`]]
13 [def __waiting__ [future_state_link `boost::future_state::waiting`]]
15 [def __future_uninitialized__ `boost::future_uninitialized`]
16 [def __broken_promise__ `boost::broken_promise`]
17 [def __future_already_retrieved__ `boost::future_already_retrieved`]
18 [def __task_moved__ `boost::task_moved`]
19 [def __task_already_started__ `boost::task_already_started`]
20 [def __promise_already_satisfied__ `boost::promise_already_satisfied`]
22 [def __thread_interrupted__ `boost::thread_interrupted`]
25 [template unique_future_link[link_text] [link thread.synchronization.futures.reference.unique_future [link_text]]]
26 [def __unique_future__ [unique_future_link `future`]]
27 [def __unique_future `future`]
29 [template unique_future_get_link[link_text] [link thread.synchronization.futures.reference.unique_future.get [link_text]]]
30 [def __unique_future_get__ [unique_future_get_link `boost::future<R>::get()`]]
32 [template unique_future_wait_link[link_text] [link thread.synchronization.futures.reference.unique_future.wait [link_text]]]
33 [def __unique_future_wait__ [unique_future_wait_link `boost::future<R>::wait()`]]
35 [template unique_future_is_ready_link[link_text] [link thread.synchronization.futures.reference.unique_future.is_ready [link_text]]]
36 [def __unique_future_is_ready__ [unique_future_is_ready_link `boost::future<R>::is_ready()`]]
38 [template unique_future_has_value_link[link_text] [link thread.synchronization.futures.reference.unique_future.has_value [link_text]]]
39 [def __unique_future_has_value__ [unique_future_has_value_link `boost::future<R>::has_value()`]]
41 [template unique_future_has_exception_link[link_text] [link thread.synchronization.futures.reference.unique_future.has_exception [link_text]]]
42 [def __unique_future_has_exception__ [unique_future_has_exception_link `boost::future<R>::has_exception()`]]
44 [template unique_future_get_state_link[link_text] [link thread.synchronization.futures.reference.unique_future.get_state [link_text]]]
45 [def __unique_future_get_state__ [unique_future_get_state_link `boost::future<R>::get_state()`]]
47 [template shared_future_link[link_text] [link thread.synchronization.futures.reference.shared_future [link_text]]]
48 [def __shared_future__ [shared_future_link `boost::shared_future`]]
50 [template shared_future_get_link[link_text] [link thread.synchronization.futures.reference.shared_future.get [link_text]]]
51 [def __shared_future_get__ [shared_future_get_link `boost::shared_future<R>::get()`]]
53 [template shared_future_wait_link[link_text] [link thread.synchronization.futures.reference.shared_future.wait [link_text]]]
54 [def __shared_future_wait__ [shared_future_wait_link `boost::shared_future<R>::wait()`]]
56 [template shared_future_is_ready_link[link_text] [link thread.synchronization.futures.reference.shared_future.is_ready [link_text]]]
57 [def __shared_future_is_ready__ [shared_future_is_ready_link `boost::shared_future<R>::is_ready()`]]
59 [template shared_future_has_value_link[link_text] [link thread.synchronization.futures.reference.shared_future.has_value [link_text]]]
60 [def __shared_future_has_value__ [shared_future_has_value_link `boost::shared_future<R>::has_value()`]]
62 [template shared_future_has_exception_link[link_text] [link thread.synchronization.futures.reference.shared_future.has_exception [link_text]]]
63 [def __shared_future_has_exception__ [shared_future_has_exception_link `boost::shared_future<R>::has_exception()`]]
65 [template shared_future_get_state_link[link_text] [link thread.synchronization.futures.reference.shared_future.get_state [link_text]]]
66 [def __shared_future_get_state__ [shared_future_get_state_link `boost::shared_future<R>::get_state()`]]
68 [template promise_link[link_text] [link thread.synchronization.futures.reference.promise [link_text]]]
69 [def __promise__ [promise_link `boost::promise`]]
71 [template packaged_task_link[link_text] [link thread.synchronization.futures.reference.packaged_task [link_text]]]
72 [def __packaged_task__ [packaged_task_link `boost::packaged_task`]]
73 [def __packaged_task [packaged_task_link `boost::packaged_task`]]
75 [template wait_for_any_link[link_text] [link thread.synchronization.futures.reference.wait_for_any [link_text]]]
76 [def __wait_for_any__ [wait_for_any_link `boost::wait_for_any()`]]
78 [template wait_for_all_link[link_text] [link thread.synchronization.futures.reference.wait_for_all [link_text]]]
79 [def __wait_for_all__ [wait_for_all_link `boost::wait_for_all()`]]
82 [section:overview Overview]
84 The futures library provides a means of handling synchronous future values, whether those values are generated by another thread, or
85 on a single thread in response to external stimuli, or on-demand.
87 This is done through the provision of four class templates: __unique_future__ and __shared_future__ which are used to retrieve the
88 asynchronous results, and __promise__ and __packaged_task__ which are used to generate the asynchronous results.
90 An instance of __unique_future__ holds the one and only reference to a result. Ownership can be transferred between instances using
91 the move constructor or move-assignment operator, but at most one instance holds a reference to a given asynchronous result. When
92 the result is ready, it is returned from __unique_future_get__ by rvalue-reference to allow the result to be moved or copied as
93 appropriate for the type.
95 On the other hand, many instances of __shared_future__ may reference the same result. Instances can be freely copied and assigned,
96 and __shared_future_get__ returns a non `const` reference so that multiple calls to __shared_future_get__ are safe. You can move an
97 instance of __unique_future__ into an instance of __shared_future__, thus transferring ownership of the associated asynchronous
98 result, but not vice-versa.
100 `boost::async` is a simple way of running asynchronous tasks. A call to `boost::async` returns a __unique_future__ that will contain the result of the task.
103 You can wait for futures either individually or with one of the __wait_for_any__ and __wait_for_all__ functions.
107 [section:creating Creating asynchronous values]
109 You can set the value in a future with either a __promise__ or a __packaged_task__. A __packaged_task__ is a callable object that
110 wraps a function or callable object. When the packaged task is invoked, it invokes the contained function in turn, and populates a
111 future with the return value. This is an answer to the perennial question: "how do I return a value from a thread?": package the
112 function you wish to run as a __packaged_task__ and pass the packaged task to the thread constructor. The future retrieved from the
113 packaged task can then be used to obtain the return value. If the function throws an exception, that is stored in the future in
114 place of the return value.
116 int calculate_the_answer_to_life_the_universe_and_everything()
121 boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
122 boost::__unique_future__<int> fi=pt.get_future();
124 boost::thread task(boost::move(pt)); // launch task on a thread
126 fi.wait(); // wait for it to finish
128 assert(fi.is_ready());
129 assert(fi.has_value());
130 assert(!fi.has_exception());
131 assert(fi.get_state()==boost::future_state::ready);
132 assert(fi.get()==42);
135 A __promise__ is a bit more low level: it just provides explicit functions to store a value or an exception in the associated
136 future. A promise can therefore be used where the value may come from more than one possible source, or where a single operation may
137 produce multiple values.
139 boost::promise<int> pi;
140 boost::__unique_future__<int> fi;
145 assert(fi.is_ready());
146 assert(fi.has_value());
147 assert(!fi.has_exception());
148 assert(fi.get_state()==boost::future_state::ready);
149 assert(fi.get()==42);
153 [section:lazy_futures Wait Callbacks and Lazy Futures]
155 Both __promise__ and __packaged_task__ support ['wait callbacks] that are invoked when a thread blocks in a call to `wait()` or
156 `timed_wait()` on a future that is waiting for the result from the __promise__ or __packaged_task__, in the thread that is doing the
157 waiting. These can be set using the `set_wait_callback()` member function on the __promise__ or __packaged_task__ in question.
159 This allows ['lazy futures] where the result is not actually computed until it is needed by some thread. In the example below, the
160 call to `f.get()` invokes the callback `invoke_lazy_task`, which runs the task to set the value. If you remove the call to
161 `f.get()`, the task is not ever run.
163 int calculate_the_answer_to_life_the_universe_and_everything()
168 void invoke_lazy_task(boost::packaged_task<int>& task)
174 catch(boost::task_already_started&)
180 boost::packaged_task<int> task(calculate_the_answer_to_life_the_universe_and_everything);
181 task.set_wait_callback(invoke_lazy_task);
182 boost::__unique_future__<int> f(task.get_future());
190 [section:at_thread_exit Handling Detached Threads and Thread Specific Variables]
192 Detached threads pose a problem for objects with thread storage duration.
193 If we use a mechanism other than `thread::__join` to wait for a __thread to complete its work - such as waiting for a future to be ready -
194 then the destructors of thread specific variables will still be running after the waiting thread has resumed.
195 This section explain how the standard mechanism can be used to make such synchronization safe by ensuring that the
196 objects with thread storage duration are destroyed prior to the future being made ready. e.g.
198 int find_the_answer(); // uses thread specific objects
199 void thread_func(boost::promise<int>&& p)
201 p.set_value_at_thread_exit(find_the_answer());
206 boost::promise<int> p;
207 boost::thread t(thread_func,boost::move(p));
208 t.detach(); // we're going to wait on the future
209 std::cout<<p.get_future().get()<<std::endl;
212 When the call to `get()` returns, we know that not only is the future value ready, but the thread specific variables
213 on the other thread have also been destroyed.
215 Such mechanisms are provided for `boost::condition_variable`, `boost::promise` and `boost::packaged_task`. e.g.
217 void task_executor(boost::packaged_task<void(int)> task,int param)
219 task.make_ready_at_thread_exit(param); // execute stored task
220 } // destroy thread specific and wake threads waiting on futures from task
222 Other threads can wait on a future obtained from the task without having to worry about races due to the execution of
223 destructors of the thread specific objects from the task's thread.
225 boost::condition_variable cv;
227 complex_type the_data;
232 boost::unique_lock<std::mutex> lk(m);
233 the_data=find_the_answer();
235 boost::notify_all_at_thread_exit(cv,boost::move(lk));
236 } // destroy thread specific objects, notify cv, unlock mutex
238 void waiting_thread()
240 boost::unique_lock<std::mutex> lk(m);
248 The waiting thread is guaranteed that the thread specific objects used by `thread_func()` have been destroyed by the time
249 `process(the_data)` is called. If the lock on `m` is released and re-acquired after setting `data_ready` and before calling
250 `boost::notify_all_at_thread_exit()` then this does NOT hold, since the thread may return from the wait due to a
255 [section:async Executing asynchronously]
257 `boost::async` is a simple way of running asynchronous tasks to make use of the available hardware concurrency.
258 A call to `boost::async` returns a `boost::future` that will contain the result of the task. Depending on
259 the launch policy, the task is either run asynchronously on its own thread or synchronously on whichever thread
260 calls the `wait()` or `get()` member functions on that `future`.
262 A launch policy of either boost::launch::async, which asks the runtime to create an asynchronous thread,
263 or boost::launch::deferred, which indicates you simply want to defer the function call until a later time (lazy evaluation).
264 This argument is optional - if you omit it your function will use the default policy.
266 For example, consider computing the sum of a very large array. The first task is to not compute asynchronously when
267 the overhead would be significant. The second task is to split the work into two pieces, one executed by the host
268 thread and one executed asynchronously.
271 int parallel_sum(int* data, int size)
275 for ( int i = 0; i < size; ++i )
278 auto handle = boost::async(parallel_sum, data+size/2, size-size/2);
279 sum += parallel_sum(data, size/2);
289 [section:shared Shared Futures]
291 `shared_future` is designed to be shared between threads,
292 that is to allow multiple concurrent get operations.
294 [heading Multiple get]
296 The second `get()` call in the following example is undefined.
298 void bad_second_use( type arg ) {
300 auto ftr = async( [=]{ return work( arg ); } );
308 use3( ftr.get() ); // second use is undefined
311 Using a `shared_future` solves the issue
313 void good_second_use( type arg ) {
315 shared_future<type> ftr = async( [=]{ return work( arg ); } );
323 use3( ftr.get() ); // second use is defined
328 Namming the return type when declaring the `shared_future` is needed; auto is not available within template argument lists.
329 Here `share()` could be used to simplify the code
331 void better_second_use( type arg ) {
333 auto ftr = async( [=]{ return work( arg ); } ).share();
341 use3( ftr.get() ); // second use is defined
344 [heading Writing on get()]
346 The user can either read or write the future avariable.
348 void write_to_get( type arg ) {
350 auto ftr = async( [=]{ return work( arg ); } ).share();
359 ftr.get() = something(); // assign to non-const reference.
361 use3( ftr.get() ); // second use is defined
364 This works because the `shared_future<>::get()` function returns a non-const reference to the appropriate storage.
365 Of course the access to this storage must be ensured by the user. The library doesn't ensure the access to the internal storage is thread safe.
367 There has been some work by the C++ standard committe on an `atomic_future` that behaves as an `atomic` variable, that is is thread_safe,
368 and a `shared_future` that can be shared between several threads, but there were not enough consensus and time to get it ready for C++11.
372 [section:make_ready_future Making immediate futures easier]
374 Some functions may know the value at the point of construction. In these cases the value is immediately available,
375 but needs to be returned as a future or shared_future. By using make_ready_future a future
376 can be created which holds a pre-computed result in its shared state.
378 Without these features it is non-trivial to create a future directly from a value.
379 First a promise must be created, then the promise is set, and lastly the future is retrieved from the promise.
380 This can now be done with one operation.
382 [heading make_ready_future]
384 This function creates a future for a given value. If no value is given then a future<void> is returned.
385 This function is primarily useful in cases where sometimes, the return value is immediately available, but sometimes
386 it is not. The example below illustrates, that in an error path the value is known immediately, however in other paths
387 the function must return an eventual value represented as a future.
390 boost::future<int> compute(int x)
392 if (x == 0) return boost::make_ready_future(0);
393 if (x < 0) return boost::make_ready_future<int>(std::logic_error("Error"));
394 boost::future<int> f1 = boost::async([]() { return x+1; });
398 There are two variations of this function. The first takes a value of any type, and returns a future of that type.
399 The input value is passed to the shared state of the returned future. The second version takes no input and returns a future<void>.
403 [section:then Associating future continuations]
405 In asynchronous programming, it is very common for one asynchronous operation, on completion, to invoke a second
406 operation and pass data to it. The current C++ standard does not allow one to register a continuation to a future.
407 With `.then`, instead of waiting for the result, a continuation is "attached" to the asynchronous operation, which is
408 invoked when the result is ready. Continuations registered using the `.then` function will help to avoid blocking waits
409 or wasting threads on polling, greatly improving the responsiveness and scalability of an application.
411 `future.then()` provides the ability to sequentially compose two futures by declaring one to be the continuation of another.
412 With `.then()` the antecedent future is ready (has a value or exception stored in the shared state) before the continuation
413 starts as instructed by the lambda function.
415 In the example below the `future<string>` `f2` is registered to be a continuation of `future<int>` `f1` using the `.then()` member
416 function. This operation takes a lambda function which describes how `f2` should proceed after `f1` is ready.
419 #include <boost/thread/future.hpp>
420 using namespace boost;
423 future<int> f1 = async([]() { return 123; });
424 future<string> f2 = f1.then([](future<int> f) { return f.get().to_string(); // here .get() won't block });
427 One key feature of this function is the ability to chain multiple asynchronous operations. In asynchronous programming,
428 it's common to define a sequence of operations, in which each continuation executes only when the previous one completes.
429 In some cases, the antecedent future produces a value that the continuation accepts as input. By using `future.then()`,
430 creating a chain of continuations becomes straightforward and intuitive:
432 myFuture.then(...).then(...).then(...).
434 Some points to note are:
436 * Each continuation will not begin until the preceding has completed.
437 * If an exception is thrown, the following continuation can handle it in a try-catch block
442 * Lambda function: One option which can be considered is to take two functions, one for
443 success and one for error handling. However this option has not been retained for the moment.
444 The lambda function takes a future as its input which carries the exception
445 through. This makes propagating exceptions straightforward. This approach also simplifies the chaining of continuations.
446 * Scheduler: Providing an overload to `.then`, to take a scheduler reference places great flexibility over the execution
447 of the future in the programmer's hand. As described above, often taking a launch policy is not sufficient for powerful
448 asynchronous operations. The lifetime of the scheduler must outlive the continuation.
449 * Launch policy: if the additional flexibility that the scheduler provides is not required.
451 Return values: The decision to return a future was based primarily on the ability to chain multiple continuations using
452 `.then()`. This benefit of composability gives the programmer incredible control and flexibility over their code. Returning
453 a `future` object rather than a `shared_future` is also a much cheaper operation thereby improving performance. A
454 `shared_future` object is not necessary to take advantage of the chaining feature. It is also easy to go from a `future`
455 to a `shared_future` when needed using future::share().
461 [include future_ref.qbk]