mirror of
https://github.com/boostorg/fiber.git
synced 2026-02-17 13:42:21 +00:00
195 lines
14 KiB
HTML
195 lines
14 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
|
<title>when_any / when_all functionality</title>
|
|
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
|
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
|
|
<link rel="home" href="../index.html" title="Chapter 1. Fiber">
|
|
<link rel="up" href="../index.html" title="Chapter 1. Fiber">
|
|
<link rel="prev" href="nonblocking.html" title="Integrating Fibers with Nonblocking I/O">
|
|
<link rel="next" href="when_any/when_any.html" title="when_any">
|
|
</head>
|
|
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
|
<table cellpadding="2" width="100%"><tr>
|
|
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
|
|
<td align="center"><a href="../../../../../index.html">Home</a></td>
|
|
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
|
|
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
|
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
|
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
|
|
</tr></table>
|
|
<hr>
|
|
<div class="spirit-nav">
|
|
<a accesskey="p" href="nonblocking.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="when_any/when_any.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
|
</div>
|
|
<div class="section">
|
|
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
|
<a name="fiber.when_any"></a><a name="when_any"></a><a class="link" href="when_any.html" title="when_any / when_all functionality">when_any / when_all
|
|
functionality</a>
|
|
</h2></div></div></div>
|
|
<div class="toc"><dl>
|
|
<dt><span class="section"><a href="when_any/when_any.html">when_any</a></span></dt>
|
|
<dd><dl>
|
|
<dt><span class="section"><a href="when_any/when_any/when_any__simple_completion.html">when_any,
|
|
simple completion</a></span></dt>
|
|
<dt><span class="section"><a href="when_any/when_any/when_any__return_value.html">when_any,
|
|
return value</a></span></dt>
|
|
<dt><span class="section"><a href="when_any/when_any/when_any__produce_first_outcome__whether_result_or_exception.html">when_any,
|
|
produce first outcome, whether result or exception</a></span></dt>
|
|
<dt><span class="section"><a href="when_any/when_any/when_any__produce_first_success.html">when_any,
|
|
produce first success</a></span></dt>
|
|
<dt><span class="section"><a href="when_any/when_any/when_any__heterogeneous_types.html">when_any,
|
|
heterogeneous types</a></span></dt>
|
|
</dl></dd>
|
|
<dt><span class="section"><a href="when_any/when_all_functionality.html">when_all functionality</a></span></dt>
|
|
<dd><dl>
|
|
<dt><span class="section"><a href="when_any/when_all_functionality/when_all__simple_completion.html">when_all,
|
|
simple completion</a></span></dt>
|
|
<dt><span class="section"><a href="when_any/when_all_functionality/when_all__return_values.html">when_all,
|
|
return values</a></span></dt>
|
|
<dt><span class="section"><a href="when_any/when_all_functionality/when_all_until_first_exception.html">when_all
|
|
until first exception</a></span></dt>
|
|
<dt><span class="section"><a href="when_any/when_all_functionality/wait_all__collecting_all_exceptions.html">wait_all,
|
|
collecting all exceptions</a></span></dt>
|
|
<dt><span class="section"><a href="when_any/when_all_functionality/when_all__heterogeneous_types.html">when_all,
|
|
heterogeneous types</a></span></dt>
|
|
</dl></dd>
|
|
</dl></div>
|
|
<h4>
|
|
<a name="fiber.when_any.h0"></a>
|
|
<span><a name="fiber.when_any.overview"></a></span><a class="link" href="when_any.html#fiber.when_any.overview">Overview</a>
|
|
</h4>
|
|
<p>
|
|
A bit of wisdom from the early days of computing still holds true today: prefer
|
|
to model program state using the instruction pointer rather than with Boolean
|
|
flags. In other words, if the program must "do something" and then
|
|
do something almost the same, but with minor changes... perhaps parts of that
|
|
something should be broken out as smaller separate functions, rather than introducing
|
|
flags to alter the internal behavior of a monolithic function.
|
|
</p>
|
|
<p>
|
|
To that we would add: prefer to describe control flow using C++ native constructs
|
|
such as function calls, <code class="computeroutput"><span class="keyword">if</span></code>, <code class="computeroutput"><span class="keyword">while</span></code>, <code class="computeroutput"><span class="keyword">for</span></code>,
|
|
<code class="computeroutput"><span class="keyword">do</span></code> et al. rather than as chains
|
|
of callbacks.
|
|
</p>
|
|
<p>
|
|
One of the great strengths of <span class="bold"><strong>Boost.Fiber</strong></span>
|
|
is the flexibility it confers on the coder to restructure an application from
|
|
chains of callbacks to straightforward C++ statement sequence, even when code
|
|
in that fiber is in fact interleaved with code running in other fibers.
|
|
</p>
|
|
<p>
|
|
There has been much recent discussion about the benefits of when_any and when_all
|
|
functionality. When dealing with asynchronous and possibly unreliable services,
|
|
these are valuable idioms. But of course when_any and when_all are closely
|
|
tied to the use of chains of callbacks.
|
|
</p>
|
|
<p>
|
|
This section presents recipes for achieving the same ends, in the context of
|
|
a fiber that wants to "do something" when one or more other independent
|
|
activities have completed. Accordingly, these are <code class="computeroutput"><span class="identifier">wait_something</span><span class="special">()</span></code> functions rather than <code class="computeroutput"><span class="identifier">when_something</span><span class="special">()</span></code> functions. The expectation is that the calling
|
|
fiber asks to launch those independent activities, then waits for them, then
|
|
sequentially proceeds with whatever processing depends on those results.
|
|
</p>
|
|
<p>
|
|
The function names shown (e.g. <a class="link" href="when_any/when_any/when_any__simple_completion.html#wait_first_simple"><code class="computeroutput"><span class="identifier">wait_first_simple</span><span class="special">()</span></code></a>)
|
|
are for illustrative purposes only, because all these functions have been bundled
|
|
into a single source file. Presumably, if (say) <a class="link" href="when_any/when_any/when_any__produce_first_success.html#wait_first_success"><code class="computeroutput"><span class="identifier">wait_first_success</span><span class="special">()</span></code></a>
|
|
best suits your application needs, you could introduce that variant with the
|
|
name <code class="computeroutput"><span class="identifier">wait_any</span><span class="special">()</span></code>.
|
|
</p>
|
|
<div class="note"><table border="0" summary="Note">
|
|
<tr>
|
|
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
|
|
<th align="left">Note</th>
|
|
</tr>
|
|
<tr><td align="left" valign="top"><p>
|
|
The functions presented in this section accept variadic argument lists of
|
|
task functions. Corresponding <code class="computeroutput"><span class="identifier">wait_something</span><span class="special">()</span></code> functions accepting a container of task
|
|
functions are left as an exercise for the interested reader. Those should
|
|
actually be simpler. Most of the complexity would arise from overloading
|
|
the same name for both purposes.
|
|
</p></td></tr>
|
|
</table></div>
|
|
<p>
|
|
All the source code for this section is found in <a href="../../../examples/wait_stuff.cpp" target="_top">wait_stuff.cpp</a>.
|
|
</p>
|
|
<h4>
|
|
<a name="fiber.when_any.h1"></a>
|
|
<span><a name="fiber.when_any.example_task_function"></a></span><a class="link" href="when_any.html#fiber.when_any.example_task_function">Example
|
|
Task Function</a>
|
|
</h4>
|
|
<p>
|
|
<a name="wait_sleeper"></a>We found it convenient to model an asynchronous
|
|
task using this function:
|
|
</p>
|
|
<p>
|
|
</p>
|
|
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span>
|
|
<span class="identifier">T</span> <span class="identifier">sleeper_impl</span><span class="special">(</span> <span class="identifier">T</span> <span class="identifier">item</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">ms</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">thrw</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">)</span> <span class="special">{</span>
|
|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">descb</span><span class="special">,</span> <span class="identifier">funcb</span><span class="special">;</span>
|
|
<span class="identifier">descb</span> <span class="special"><<</span> <span class="identifier">item</span><span class="special">;</span>
|
|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">desc</span><span class="special">(</span> <span class="identifier">descb</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">);</span>
|
|
<span class="identifier">funcb</span> <span class="special"><<</span> <span class="string">" sleeper("</span> <span class="special"><<</span> <span class="identifier">item</span> <span class="special"><<</span> <span class="string">")"</span><span class="special">;</span>
|
|
<span class="identifier">Verbose</span> <span class="identifier">v</span><span class="special">(</span> <span class="identifier">funcb</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">);</span>
|
|
|
|
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">sleep_for</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">milliseconds</span><span class="special">(</span> <span class="identifier">ms</span><span class="special">)</span> <span class="special">);</span>
|
|
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">thrw</span><span class="special">)</span> <span class="special">{</span>
|
|
<span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span> <span class="identifier">desc</span><span class="special">);</span>
|
|
<span class="special">}</span>
|
|
<span class="keyword">return</span> <span class="identifier">item</span><span class="special">;</span>
|
|
<span class="special">}</span>
|
|
</pre>
|
|
<p>
|
|
</p>
|
|
<p>
|
|
with type-specific <code class="computeroutput"><span class="identifier">sleeper</span><span class="special">()</span></code> "front ends" for <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>,
|
|
<code class="computeroutput"><span class="keyword">double</span></code> and <code class="computeroutput"><span class="keyword">int</span></code>.
|
|
</p>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">Verbose</span></code> simply prints a message
|
|
to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></code> on construction and destruction.
|
|
</p>
|
|
<p>
|
|
Basically:
|
|
</p>
|
|
<div class="orderedlist"><ol class="orderedlist" type="1">
|
|
<li class="listitem">
|
|
<code class="computeroutput"><span class="identifier">sleeper</span><span class="special">()</span></code>
|
|
prints a start message;
|
|
</li>
|
|
<li class="listitem">
|
|
sleeps for the specified number of milliseconds;
|
|
</li>
|
|
<li class="listitem">
|
|
if <code class="computeroutput"><span class="identifier">thrw</span></code> is passed as <code class="computeroutput"><span class="keyword">true</span></code>, throws a string description of the
|
|
passed <code class="computeroutput"><span class="identifier">item</span></code>;
|
|
</li>
|
|
<li class="listitem">
|
|
else returns the passed <code class="computeroutput"><span class="identifier">item</span></code>.
|
|
</li>
|
|
<li class="listitem">
|
|
On the way out, <code class="computeroutput"><span class="identifier">sleeper</span><span class="special">()</span></code> produces a stop message.
|
|
</li>
|
|
</ol></div>
|
|
<p>
|
|
This function will feature in the example calls to the various functions presented
|
|
below.
|
|
</p>
|
|
</div>
|
|
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
|
<td align="left"></td>
|
|
<td align="right"><div class="copyright-footer">Copyright © 2013 Oliver Kowalke<p>
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
|
</p>
|
|
</div></td>
|
|
</tr></table>
|
|
<hr>
|
|
<div class="spirit-nav">
|
|
<a accesskey="p" href="nonblocking.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="when_any/when_any.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
|
</div>
|
|
</body>
|
|
</html>
|