Библиотека фьючерсов предоставляет средства обработки асинхронных будущих значений, независимо от того, генерируются ли эти значения другим волокном или одним волокном в ответ на внешние раздражители или по требованию.
Это делается путем предоставления четырех шаблонов классов:<future<>
>и<shared_future<>
>, которые используются для получения асинхронных результатов, и<promise<>
>и<packaged_task<>
>, которые используются для получения асинхронных результатов.
Пример<future<>
>содержит только одну ссылку на результат. Владение может быть передано между экземплярами с использованием конструктора хода или оператора назначения хода, но в большинстве случаев один экземпляр содержит ссылку на заданный асинхронный результат. Когда результат готов, он возвращается из<future::get()
>путем ссылки на значение, чтобы позволить результату перемещаться или копироваться в соответствии с типом.
С другой стороны, многие примеры<shared_future<>
>могут ссылаться на тот же результат. Случаи могут быть свободно скопированы и назначены, и<shared_future::get()
>возвращает<const
>ссылку, так что несколько звонков<shared_future::get()
>безопасны. Вы можете переместить экземпляр<future<>
>в экземпляр<shared_future<>
>, таким образом передавая право собственности на асинхронный результат, но не наоборот.
<fibers::async()
>— простой способ выполнения асинхронных задач. Призыв к<async()
>порождает волокно и возвращает<future<>
>, которые будут доставлять результат функции волокна.
Вы можете установить значение в будущем либо с<promise<>
>, либо с<packaged_task<>
>. А<packaged_task<>
>является вызывающим объектом с<void
>возвратом, который обертывает функцию или вызывающий объект, возвращающий указанный тип. Когда<packaged_task<>
>вызывается, она, в свою очередь, вызывает содержащуюся функцию и населяет будущее обратным значением содержащей функции. Это ответ на вечный вопрос:& #8220;Как вернуть значение из волокна?& #8221;Упакуйте функцию, которую вы хотите запустить как<packaged_task<>
>, и передайте упакованную задачу конструктору волокна. Будущее, извлеченное из упакованной задачи, затем может быть использовано для получения возвращаемого значения. Если функция выбрасывает исключение, то оно хранится в будущем вместо возвращаемого значения.
int calculate_the_answer_to_life_the_universe_and_everything() {
return 42;
}
boost::fibers::packaged_task<int()> pt(calculate_the_answer_to_life_the_universe_and_everything);
boost::fibers::future<int> fi=pt.get_future();
boost::fibers::fiber(std::move(pt)).detach();
fi.wait();
assert(fi.is_ready());
assert(fi.has_value());
assert(!fi.has_exception());
assert(fi.get()==42);
A<promise<>
>является немного более низким уровнем: он просто предоставляет явные функции для хранения значения или исключения в связанном будущем. Таким образом, обещание может быть использовано там, где стоимость может быть получена из более чем одного возможного источника.
boost::fibers::promise<int> pi;
boost::fibers::future<int> fi;
fi=pi.get_future();
pi.set_value(42);
assert(fi.is_ready());
assert(fi.has_value());
assert(!fi.has_exception());
assert(fi.get()==42);