D.4.5. Шаблон функции std::async
Шаблон функции std::async дает простой способ выполнить автономную асинхронную задачу с использованием доступного аппаратного параллелизма. Обращение к std::async возвращает объект std::future, который содержит результат задачи. В зависимости от политики запуска задача выполняется либо асинхронно в отдельном потоке, либо синхронно в том потоке, который вызвал функции-члены wait() или get() объекта std::future.
Объявление
enum class launch {
async, deferred
};
template<typename Callable, typename... Args>
future<result_of<Callable(Args...)>::type>
async(Callable&& func, Args&& ... args);
template<typename Callable, typename ... Args>
future<result_of<Callable(Args...)>::type>
async(launch policy, Callable&& func, Args&& ... args);
Предусловия
Выражение INVOKE(func, args) допустимо для переданных значений func и args. Тип Callable и все члены Args удовлетворяют требованиям концепции MoveConstructible.
Результат
Конструирует копии func и args... во внутренней памяти (далее обозначаются fff и xyz... соответственно).
Если policy равно std::launch::async, то вызывает функцию INVOKE(fff, xyz...) в отдельном потоке. Возвращенный объект std::future становится готов, когда этот поток завершится, и будет содержать либо возвращенное функцией значение, либо возбужденное ей исключение. Деструктор последнего будущего объекта, ассоциированного с асинхронным состоянием возвращенного объекта std::future, блокирует поток, пока будущий результат не будет готов.
Если policy равно std::launch::deferred, то fff и xyz... сохраняются в возвращенном объекте std::future как отложенный вызов функции. При первом обращении к функции-члену wait() или get() будущего результата, который разделяет то же самое ассоциированное состояние, функция INVOKE(fff, xyz...) синхронно вызывается в потоке, который обратился к wait() или get().
В ответ на вызов функции get() этого объекта std::future либо возвращается значение, полученное от INVOKE(fff, xyz...), либо возбуждается исключение, которое имело место в этой функции.
Если policy равно std::launch::async | std::launch::deferred или аргумент policy опущен, то поведение такое же, как если бы была задана политика std::launch::async или std::launch::deferred. Реализация сама выбирает нужное поведение при каждом вызове, чтобы в максимальной степени задействовать доступный аппаратный параллелизм, не вызывая при этом превышения лимита.
В любом случае функция std::async возвращает управление немедленно.
Синхронизация
Завершение вызова функции происходит-раньше успешного возврата из функций wait(), get(), wait_for() и wait_until() любого экземпляра std::future или std::shared_future, который ссылается на то же ассоциированное состояние, что и объект std::future, возвращенный функцией std::async. Если policy равно std::launch::async, то завершение потока, в котором имел место вызов std::async, также происходит-раньше успешного возврата из этих функций.
Исключения
std::bad_alloc, если не удалось выделить внутреннюю память или std::future_error, если не удалось добиться желаемого эффекта, или исключение, возбужденное в ходе конструирования fff или xyz....