futures.qbk 3.5 KB

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