Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / thread / doc / futures.qbk
1 [/
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).
6 ]
7
8 [section:futures Futures]
9
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`]]
14
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`]
21
22 [def __thread_interrupted__ `boost::thread_interrupted`]
23
24
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`]
28
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()`]]
31
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()`]]
34
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()`]]
37
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()`]]
40
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()`]]
43
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()`]]
46
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`]]
49
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()`]]
52
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()`]]
55
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()`]]
58
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()`]]
61
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()`]]
64
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()`]]
67
68 [template promise_link[link_text] [link thread.synchronization.futures.reference.promise [link_text]]]
69 [def __promise__ [promise_link `boost::promise`]]
70
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`]]
74
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()`]]
77
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()`]]
80
81
82 [section:overview Overview]
83
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.
86
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.
89
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.
94
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.
99
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.
101
102
103 You can wait for futures either individually or with one of the __wait_for_any__ and __wait_for_all__ functions.
104
105 [endsect]
106
107 [section:creating Creating asynchronous values]
108
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.
115
116     int calculate_the_answer_to_life_the_universe_and_everything()
117     {
118         return 42;
119     }
120
121     boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
122     boost::__unique_future__<int> fi=pt.get_future();
123
124     boost::thread task(boost::move(pt)); // launch task on a thread
125
126     fi.wait(); // wait for it to finish
127         
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);
133
134
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.
138
139     boost::promise<int> pi;
140     boost::__unique_future__<int> fi;
141     fi=pi.get_future();
142
143     pi.set_value(42);
144     
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);
150
151 [endsect]
152
153 [section:lazy_futures Wait Callbacks and Lazy Futures]
154
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.
158
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.
162
163     int calculate_the_answer_to_life_the_universe_and_everything()
164     {
165         return 42;
166     }
167
168     void invoke_lazy_task(boost::packaged_task<int>& task)
169     {
170         try
171         {
172             task();
173         }
174         catch(boost::task_already_started&)
175         {}
176     }
177
178     int main()
179     {
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());
183
184         assert(f.get()==42);
185     }
186
187
188 [endsect]
189
190 [section:at_thread_exit Handling Detached Threads and Thread Specific Variables]
191
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.
197
198   int find_the_answer(); // uses thread specific objects
199   void thread_func(boost::promise<int>&& p)
200   {
201       p.set_value_at_thread_exit(find_the_answer());
202   }
203   
204   int main()
205   {
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;
210   }
211
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.
214
215 Such mechanisms are provided for `boost::condition_variable`, `boost::promise` and `boost::packaged_task`. e.g.
216
217   void task_executor(boost::packaged_task<void(int)> task,int param)
218   {
219       task.make_ready_at_thread_exit(param); // execute stored task
220   } // destroy thread specific and wake threads waiting on futures from task
221
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.
224
225   boost::condition_variable cv;
226   boost::mutex m;
227   complex_type the_data;
228   bool data_ready;
229   
230   void thread_func()
231   {
232       boost::unique_lock<std::mutex> lk(m);
233       the_data=find_the_answer();
234       data_ready=true;
235       boost::notify_all_at_thread_exit(cv,boost::move(lk));
236   } // destroy thread specific objects, notify cv, unlock mutex
237   
238   void waiting_thread()
239   {
240       boost::unique_lock<std::mutex> lk(m);
241       while(!data_ready)
242       {
243           cv.wait(lk);
244       }
245       process(the_data);
246   }
247
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 
251 spurious wake-up.
252
253 [endsect]
254
255 [section:async Executing asynchronously]
256
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`.
261
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.
265
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.
269
270
271     int parallel_sum(int* data, int size)
272     {
273       int sum = 0;
274       if ( size < 1000 )
275         for ( int i = 0; i < size; ++i )
276           sum += data[i];
277       else {
278         auto handle = boost::async(parallel_sum, data+size/2, size-size/2);
279         sum += parallel_sum(data, size/2);
280         sum += handle.get();
281       }
282       return sum;
283     }
284
285
286
287 [endsect]
288
289 [section:shared Shared Futures]
290
291 `shared_future` is designed to be shared between threads, 
292 that is to allow multiple concurrent get operations.
293
294 [heading Multiple get]
295
296 The second `get()` call in the following example is undefined.  
297
298   void bad_second_use( type arg ) {
299       
300     auto ftr = async( [=]{ return work( arg ); } );
301       if ( cond1 ) 
302       {
303           use1( ftr.get() );
304       } else 
305       {
306           use2( ftr.get() );
307       }
308       use3( ftr.get() ); // second use is undefined
309   }
310     
311 Using a `shared_future` solves the issue
312
313   void good_second_use( type arg ) {
314       
315      shared_future<type> ftr = async( [=]{ return work( arg ); } );
316       if ( cond1 ) 
317       {
318           use1( ftr.get() );
319       } else 
320       {
321           use2(  ftr.get() );
322       }
323       use3( ftr.get() ); // second use is defined
324   }
325
326 [heading share()]
327   
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
330
331   void better_second_use( type arg ) {
332       
333      auto ftr = async( [=]{ return work( arg ); } ).share();
334       if ( cond1 ) 
335       {
336           use1( ftr.get() );
337       } else 
338       {
339           use2(  ftr.get() );
340       }
341       use3( ftr.get() ); // second use is defined
342   }
343  
344 [heading Writing on get()]
345
346 The user can either read or write the future avariable. 
347
348   void write_to_get( type arg ) {
349       
350      auto ftr = async( [=]{ return work( arg ); } ).share();
351       if ( cond1 ) 
352       {
353           use1( ftr.get() );
354       } else 
355       {
356         if ( cond2 ) 
357           use2(  ftr.get() );
358         else
359           ftr.get() = something(); // assign to non-const reference.  
360       }
361       use3( ftr.get() ); // second use is defined
362   }
363      
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.
366
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.       
369
370 [endsect]
371
372 [section:make_ready_future Making immediate futures easier]
373
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.
377  
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.
381
382 [heading make_ready_future]
383
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.
388
389
390   boost::future<int> compute(int x)
391   {
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; });
395     return f1;
396   }
397   
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>. 
400
401 [endsect]
402
403 [section:then Associating future continuations]
404
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.
410
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.
414
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.
417
418
419   #include <boost/thread/future.hpp>
420   using namespace boost;
421   int main() 
422   {
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 });
425   }
426
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: 
431
432   myFuture.then(...).then(...).then(...). 
433   
434 Some points to note are:
435
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
438
439
440 Input Parameters:
441
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.
450
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().
456
457
458 [endsect]
459
460
461 [include future_ref.qbk]
462
463 [endsect]