2 (C) Copyright 2008-11 Anthony Williams.
3 (C) Copyright 2012-2015 Vicente J. Botet Escriba.
4 Distributed under the Boost Software License, Version 1.0.
5 (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
9 [section:futures Futures]
11 [template future_state_link[link_text] [link thread.synchronization.futures.reference.future_state [link_text]]]
12 [def __uninitialized__ [future_state_link `boost::future_state::uninitialized`]]
13 [def __ready__ [future_state_link `boost::future_state::ready`]]
14 [def __waiting__ [future_state_link `boost::future_state::waiting`]]
16 [def __future_uninitialized__ `boost::future_uninitialized`]
17 [def __broken_promise__ `boost::broken_promise`]
18 [def __future_already_retrieved__ `boost::future_already_retrieved`]
19 [def __task_moved__ `boost::task_moved`]
20 [def __task_already_started__ `boost::task_already_started`]
21 [def __promise_already_satisfied__ `boost::promise_already_satisfied`]
23 [def __thread_interrupted__ `boost::thread_interrupted`]
26 [template unique_future_link[link_text] [link thread.synchronization.futures.reference.unique_future [link_text]]]
27 [def __unique_future__ [unique_future_link `future`]]
28 [def __unique_future `future`]
30 [template unique_future_get_link[link_text] [link thread.synchronization.futures.reference.unique_future.get [link_text]]]
31 [def __unique_future_get__ [unique_future_get_link `boost::future<R>::get()`]]
33 [template unique_future_wait_link[link_text] [link thread.synchronization.futures.reference.unique_future.wait [link_text]]]
34 [def __unique_future_wait__ [unique_future_wait_link `boost::future<R>::wait()`]]
36 [template unique_future_is_ready_link[link_text] [link thread.synchronization.futures.reference.unique_future.is_ready [link_text]]]
37 [def __unique_future_is_ready__ [unique_future_is_ready_link `boost::future<R>::is_ready()`]]
39 [template unique_future_has_value_link[link_text] [link thread.synchronization.futures.reference.unique_future.has_value [link_text]]]
40 [def __unique_future_has_value__ [unique_future_has_value_link `boost::future<R>::has_value()`]]
42 [template unique_future_has_exception_link[link_text] [link thread.synchronization.futures.reference.unique_future.has_exception [link_text]]]
43 [def __unique_future_has_exception__ [unique_future_has_exception_link `boost::future<R>::has_exception()`]]
45 [template unique_future_get_state_link[link_text] [link thread.synchronization.futures.reference.unique_future.get_state [link_text]]]
46 [def __unique_future_get_state__ [unique_future_get_state_link `boost::future<R>::get_state()`]]
48 [template shared_future_link[link_text] [link thread.synchronization.futures.reference.shared_future [link_text]]]
49 [def __shared_future__ [shared_future_link `boost::shared_future`]]
51 [template shared_future_get_link[link_text] [link thread.synchronization.futures.reference.shared_future.get [link_text]]]
52 [def __shared_future_get__ [shared_future_get_link `boost::shared_future<R>::get()`]]
54 [template shared_future_wait_link[link_text] [link thread.synchronization.futures.reference.shared_future.wait [link_text]]]
55 [def __shared_future_wait__ [shared_future_wait_link `boost::shared_future<R>::wait()`]]
57 [template shared_future_is_ready_link[link_text] [link thread.synchronization.futures.reference.shared_future.is_ready [link_text]]]
58 [def __shared_future_is_ready__ [shared_future_is_ready_link `boost::shared_future<R>::is_ready()`]]
60 [template shared_future_has_value_link[link_text] [link thread.synchronization.futures.reference.shared_future.has_value [link_text]]]
61 [def __shared_future_has_value__ [shared_future_has_value_link `boost::shared_future<R>::has_value()`]]
63 [template shared_future_has_exception_link[link_text] [link thread.synchronization.futures.reference.shared_future.has_exception [link_text]]]
64 [def __shared_future_has_exception__ [shared_future_has_exception_link `boost::shared_future<R>::has_exception()`]]
66 [template shared_future_get_state_link[link_text] [link thread.synchronization.futures.reference.shared_future.get_state [link_text]]]
67 [def __shared_future_get_state__ [shared_future_get_state_link `boost::shared_future<R>::get_state()`]]
69 [template promise_link[link_text] [link thread.synchronization.futures.reference.promise [link_text]]]
70 [def __promise__ [promise_link `boost::promise`]]
72 [template packaged_task_link[link_text] [link thread.synchronization.futures.reference.packaged_task [link_text]]]
73 [def __packaged_task__ [packaged_task_link `boost::packaged_task`]]
74 [def __packaged_task [packaged_task_link `boost::packaged_task`]]
76 [template wait_for_any_link[link_text] [link thread.synchronization.futures.reference.wait_for_any [link_text]]]
77 [def __wait_for_any__ [wait_for_any_link `boost::wait_for_any()`]]
79 [template wait_for_all_link[link_text] [link thread.synchronization.futures.reference.wait_for_all [link_text]]]
80 [def __wait_for_all__ [wait_for_all_link `boost::wait_for_all()`]]
83 [section:overview Overview]
85 The futures library provides a means of handling synchronous future values, whether those values are generated by another thread, or
86 on a single thread in response to external stimuli, or on-demand.
88 This is done through the provision of four class templates: __unique_future__ and __shared_future__ which are used to retrieve the
89 asynchronous results, and __promise__ and __packaged_task__ which are used to generate the asynchronous results.
91 An instance of __unique_future__ holds the one and only reference to a result. Ownership can be transferred between instances using
92 the move constructor or move-assignment operator, but at most one instance holds a reference to a given asynchronous result. When
93 the result is ready, it is returned from __unique_future_get__ by rvalue-reference to allow the result to be moved or copied as
94 appropriate for the type.
96 On the other hand, many instances of __shared_future__ may reference the same result. Instances can be freely copied and assigned,
97 and __shared_future_get__ returns a `const` reference so that multiple calls to __shared_future_get__ are safe. You can move an
98 instance of __unique_future__ into an instance of __shared_future__, thus transferring ownership of the associated asynchronous
99 result, but not vice-versa.
101 `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.
104 You can wait for futures either individually or with one of the __wait_for_any__ and __wait_for_all__ functions.
108 [section:creating Creating asynchronous values]
110 You can set the value in a future with either a __promise__ or a __packaged_task__. A __packaged_task__ is a callable object that
111 wraps a function or callable object. When the packaged task is invoked, it invokes the contained function in turn, and populates a
112 future with the return value. This is an answer to the perennial question: "how do I return a value from a thread?": package the
113 function you wish to run as a __packaged_task__ and pass the packaged task to the thread constructor. The future retrieved from the
114 packaged task can then be used to obtain the return value. If the function throws an exception, that is stored in the future in
115 place of the return value.
117 int calculate_the_answer_to_life_the_universe_and_everything()
122 boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
123 boost::__unique_future__<int> fi=pt.get_future();
125 boost::thread task(boost::move(pt)); // launch task on a thread
127 fi.wait(); // wait for it to finish
129 assert(fi.is_ready());
130 assert(fi.has_value());
131 assert(!fi.has_exception());
132 assert(fi.get_state()==boost::future_state::ready);
133 assert(fi.get()==42);
136 A __promise__ is a bit more low level: it just provides explicit functions to store a value or an exception in the associated
137 future. A promise can therefore be used where the value may come from more than one possible source, or where a single operation may
138 produce multiple values.
140 boost::promise<int> pi;
141 boost::__unique_future__<int> fi;
146 assert(fi.is_ready());
147 assert(fi.has_value());
148 assert(!fi.has_exception());
149 assert(fi.get_state()==boost::future_state::ready);
150 assert(fi.get()==42);
154 [section:lazy_futures Wait Callbacks and Lazy Futures]
156 Both __promise__ and __packaged_task__ support ['wait callbacks] that are invoked when a thread blocks in a call to `wait()` or
157 `timed_wait()` on a future that is waiting for the result from the __promise__ or __packaged_task__, in the thread that is doing the
158 waiting. These can be set using the `set_wait_callback()` member function on the __promise__ or __packaged_task__ in question.
160 This allows ['lazy futures] where the result is not actually computed until it is needed by some thread. In the example below, the
161 call to `f.get()` invokes the callback `invoke_lazy_task`, which runs the task to set the value. If you remove the call to
162 `f.get()`, the task is not ever run.
164 int calculate_the_answer_to_life_the_universe_and_everything()
169 void invoke_lazy_task(boost::packaged_task<int>& task)
175 catch(boost::task_already_started&)
181 boost::packaged_task<int> task(calculate_the_answer_to_life_the_universe_and_everything);
182 task.set_wait_callback(invoke_lazy_task);
183 boost::__unique_future__<int> f(task.get_future());
191 [section:at_thread_exit Handling Detached Threads and Thread Specific Variables]
193 Detached threads pose a problem for objects with thread storage duration.
194 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 -
195 then the destructors of thread specific variables will still be running after the waiting thread has resumed.
196 This section explain how the standard mechanism can be used to make such synchronization safe by ensuring that the
197 objects with thread storage duration are destroyed prior to the future being made ready. e.g.
199 int find_the_answer(); // uses thread specific objects
200 void thread_func(boost::promise<int>&& p)
202 p.set_value_at_thread_exit(find_the_answer());
207 boost::promise<int> p;
208 boost::thread t(thread_func,boost::move(p));
209 t.detach(); // we're going to wait on the future
210 std::cout<<p.get_future().get()<<std::endl;
213 When the call to `get()` returns, we know that not only is the future value ready, but the thread specific variables
214 on the other thread have also been destroyed.
216 Such mechanisms are provided for `boost::condition_variable`, `boost::promise` and `boost::packaged_task`. e.g.
218 void task_executor(boost::packaged_task<void(int)> task,int param)
220 task.make_ready_at_thread_exit(param); // execute stored task
221 } // destroy thread specific and wake threads waiting on futures from task
223 Other threads can wait on a future obtained from the task without having to worry about races due to the execution of
224 destructors of the thread specific objects from the task's thread.
226 boost::condition_variable cv;
228 complex_type the_data;
233 boost::unique_lock<std::mutex> lk(m);
234 the_data=find_the_answer();
236 boost::notify_all_at_thread_exit(cv,boost::move(lk));
237 } // destroy thread specific objects, notify cv, unlock mutex
239 void waiting_thread()
241 boost::unique_lock<std::mutex> lk(m);
249 The waiting thread is guaranteed that the thread specific objects used by `thread_func()` have been destroyed by the time
250 `process(the_data)` is called. If the lock on `m` is released and re-acquired after setting `data_ready` and before calling
251 `boost::notify_all_at_thread_exit()` then this does NOT hold, since the thread may return from the wait due to a
256 [section:async Executing asynchronously]
258 `boost::async` is a simple way of running asynchronous tasks to make use of the available hardware concurrency.
259 A call to `boost::async` returns a `boost::future` that will contain the result of the task. Depending on
260 the launch policy, the task is either run asynchronously on its own thread or synchronously on whichever thread
261 calls the `wait()` or `get()` member functions on that `future`.
263 A launch policy of either boost::launch::async, which asks the runtime to create an asynchronous thread,
264 or boost::launch::deferred, which indicates you simply want to defer the function call until a later time (lazy evaluation).
265 This argument is optional - if you omit it your function will use the default policy.
267 For example, consider computing the sum of a very large array. The first task is to not compute asynchronously when
268 the overhead would be significant. The second task is to split the work into two pieces, one executed by the host
269 thread and one executed asynchronously.
272 int parallel_sum(int* data, int size)
276 for ( int i = 0; i < size; ++i )
279 auto handle = boost::async(parallel_sum, data+size/2, size-size/2);
280 sum += parallel_sum(data, size/2);
290 [section:shared Shared Futures]
292 `shared_future` is designed to be shared between threads,
293 that is to allow multiple concurrent get operations.
295 [heading Multiple get]
297 The second `get()` call in the following example is undefined.
299 void bad_second_use( type arg ) {
301 auto ftr = async( [=]{ return work( arg ); } );
309 use3( ftr.get() ); // second use is undefined
312 Using a `shared_future` solves the issue
314 void good_second_use( type arg ) {
316 shared_future<type> ftr = async( [=]{ return work( arg ); } );
324 use3( ftr.get() ); // second use is defined
329 Naming the return type when declaring the `shared_future` is needed; auto is not available within template argument lists.
330 Here `share()` could be used to simplify the code
332 void better_second_use( type arg ) {
334 auto ftr = async( [=]{ return work( arg ); } ).share();
342 use3( ftr.get() ); // second use is defined
345 [heading Writing on get()]
347 The user can either read or write the future variable.
349 void write_to_get( type arg ) {
351 auto ftr = async( [=]{ return work( arg ); } ).share();
360 ftr.get() = something(); // assign to non-const reference.
362 use3( ftr.get() ); // second use is defined
365 This works because the `shared_future<>::get()` function returns a non-const reference to the appropriate storage.
366 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.
368 There has been some work by the C++ standard committee on an `atomic_future` that behaves as an `atomic` variable, that is thread_safe,
369 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.
373 [section:make_ready_future Making immediate futures easier]
375 Some functions may know the value at the point of construction. In these cases the value is immediately available,
376 but needs to be returned as a future or shared_future. By using make_ready_future a future
377 can be created which holds a pre-computed result in its shared state.
379 Without these features it is non-trivial to create a future directly from a value.
380 First a promise must be created, then the promise is set, and lastly the future is retrieved from the promise.
381 This can now be done with one operation.
383 [heading make_ready_future]
385 This function creates a future for a given value. If no value is given then a future<void> is returned.
386 This function is primarily useful in cases where sometimes, the return value is immediately available, but sometimes
387 it is not. The example below illustrates, that in an error path the value is known immediately, however in other paths
388 the function must return an eventual value represented as a future.
391 boost::future<int> compute(int x)
393 if (x == 0) return boost::make_ready_future(0);
394 if (x < 0) return boost::make_ready_future<int>(std::logic_error("Error"));
395 boost::future<int> f1 = boost::async([]() { return x+1; });
399 There are two variations of this function. The first takes a value of any type, and returns a future of that type.
400 The input value is passed to the shared state of the returned future. The second version takes no input and returns a future<void>.
404 [section:then Associating future continuations]
406 In asynchronous programming, it is very common for one asynchronous operation, on completion, to invoke a second
407 operation and pass data to it. The current C++ standard does not allow one to register a continuation to a future.
408 With `.then`, instead of waiting for the result, a continuation is "attached" to the asynchronous operation, which is
409 invoked when the result is ready. Continuations registered using the `.then` function will help to avoid blocking waits
410 or wasting threads on polling, greatly improving the responsiveness and scalability of an application.
412 `future.then()` provides the ability to sequentially compose two futures by declaring one to be the continuation of another.
413 With `.then()` the antecedent future is ready (has a value or exception stored in the shared state) before the continuation
414 starts as instructed by the lambda function.
416 In the example below the `future<string>` `f2` is registered to be a continuation of `future<int>` `f1` using the `.then()` member
417 function. This operation takes a lambda function which describes how `f2` should proceed after `f1` is ready.
420 #include <boost/thread/future.hpp>
421 using namespace boost;
424 future<int> f1 = async([]() { return 123; });
425 future<string> f2 = f1.then([](future<int> f) { return f.get().to_string(); // here .get() won't block });
428 One key feature of this function is the ability to chain multiple asynchronous operations. In asynchronous programming,
429 it's common to define a sequence of operations, in which each continuation executes only when the previous one completes.
430 In some cases, the antecedent future produces a value that the continuation accepts as input. By using `future.then()`,
431 creating a chain of continuations becomes straightforward and intuitive:
433 myFuture.then(...).then(...).then(...).
435 Some points to note are:
437 * Each continuation will not begin until the preceding has completed.
438 * If an exception is thrown, the following continuation can handle it in a try-catch block
443 * Lambda function: One option which can be considered is to take two functions, one for
444 success and one for error handling. However this option has not been retained for the moment.
445 The lambda function takes a future as its input which carries the exception
446 through. This makes propagating exceptions straightforward. This approach also simplifies the chaining of continuations.
447 * Executor: Providing an overload to `.then`, to take an executor reference places great flexibility over the execution
448 of the future in the programmer's hand. As described above, often taking a launch policy is not sufficient for powerful
449 asynchronous operations. The lifetime of the executor must outlive the continuation.
450 * Launch policy: if the additional flexibility that the executor provides is not required.
452 Return values: The decision to return a future was based primarily on the ability to chain multiple continuations using
453 `.then()`. This benefit of composability gives the programmer incredible control and flexibility over their code. Returning
454 a `future` object rather than a `shared_future` is also a much cheaper operation thereby improving performance. A
455 `shared_future` object is not necessary to take advantage of the chaining feature. It is also easy to go from a `future`
456 to a `shared_future` when needed using future::share().
462 [include future_ref.qbk]