...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
For the case in which we must wait for all task functions
to complete — but we don't need results (or expect exceptions) from any of
them — we can write wait_all_simple()
that looks remarkably like wait_first_simple()
.
The difference is that instead of our Done
class, we instantiate a barrier
and
call its barrier::wait()
.
We initialize the barrier
with (count+1)
because we are launching count
fibers, plus the wait()
call within wait_all_simple()
itself.
template< typename ... Fns > void wait_all_simple( Fns && ... functions) { std::size_t count( sizeof ... ( functions) ); // Initialize a barrier(count+1) because we'll immediately wait on it. We // don't want to wake up until 'count' more fibers wait on it. Even though // we'll stick around until the last of them completes, use shared_ptr // anyway because it's easier to be confident about lifespan issues. auto barrier( std::make_shared< boost::fibers::barrier >( count + 1) ); wait_all_simple_impl( barrier, std::forward< Fns >( functions) ... ); barrier->wait(); }
As stated above, the only difference between wait_all_simple_impl()
and wait_first_simple_impl()
is that the former calls barrier::wait()
rather than Done::notify()
:
template< typename Fn, typename ... Fns > void wait_all_simple_impl( std::shared_ptr< boost::fibers::barrier > barrier, Fn && function, Fns && ... functions) { boost::fibers::fiber( std::bind( []( std::shared_ptr< boost::fibers::barrier > & barrier, typename std::decay< Fn >::type & function) mutable { function(); barrier->wait(); }, barrier, std::forward< Fn >( function) )).detach(); wait_all_simple_impl( barrier, std::forward< Fns >( functions) ... ); }
You might call it like this:
wait_all_simple( [](){ sleeper("was_long", 150); }, [](){ sleeper("was_medium", 100); }, [](){ sleeper("was_short", 50); });
Control will not return from the wait_all_simple()
call until the last of its task functions
has completed.