Для случая, в котором мы должны ждатьвсефункции задачи для завершения — но нам не нужны результаты (или ожидаем исключения) от любого из них — мы можем написать<wait_all_simple()
>, который выглядит удивительно как<wait_first_simple()
>. Разница в том, что вместо нашего<Done
>класс, мы создаем<barrier
>и назвать его<barrier::wait()
>.
Мы начинаем<barrier
>с<(count+1)
>, потому что мы запускаем<count
>волокна, плюс<wait()
>вызов внутри<wait_all_simple()
>.
template< typename ... Fns >
void wait_all_simple( Fns && ... functions) {
std::size_t count( sizeof ... ( functions) );
auto barrier( std::make_shared< boost::fibers::barrier >( count + 1) );
wait_all_simple_impl( barrier, std::forward< Fns >( functions) ... );
barrier->wait();
}
Как было сказано выше, единственное различие между<wait_all_simple_impl()
>и<wait_first_simple_impl()
>заключается в том, что первые призывают<barrier::wait()
>, а не<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) ... );
}
Вы можете назвать это так:
wait_all_simple(
[](){ sleeper("was_long", 150); },
[](){ sleeper("was_medium", 100); },
[](){ sleeper("was_short", 50); });
Контроль не вернется с вызова<wait_all_simple()
>до тех пор, пока не завершится последняя из его рабочих функций.