Параллельное программирование на С++ в действии — страница 49 из 53

future>

В заголовке

объявлены средства для обработки результатов асинхронных операций, которые могли быть выполнены в другом потоке.

Содержимое заголовка

namespace std {

enum class future_status {

 ready, timeout, deferred

};


enum class future_errc {

 broken_promise,

 future_already_retrieved,

 promise_already_satisfied,

 no_state

};


class future_error;


const error_category& future_category();

error_code make_error_code(future_errc e);

error_condition make_error_condition(future_errc e);


template

class future;


template

class shared_future;


template

class promise;


template

class packaged_task; // определение не предоставляется


template

class packaged_task;


enum class launch {

 async, deferred

};


template

future::type>

async(FunctionType&& func, Args&& ... args);


template

future::type>

async(std::launch policy, FunctionType&& func, Args&& ... args);

}

D.4.1. Шаблон класса
std::future

Шаблон класса

std::future
предоставляет средства для ожидания результата асинхронной операции, начатой в другом потоке, и используется в сочетании с шаблонами классов
std::promise
и
std::packaged_task
и шаблоном функции
std::async
, которая применяется для возврата асинхронного результата. В каждый момент времени только один экземпляр
std::future
может ссылаться на данный асинхронный результат.

Экземпляры

std::future
удовлетворяют требованиям концепций
MoveConstructible
и
MoveAssignable
, но не концепций
CopyConstructible
и
CopyAssignable
.

Определение класса

template

class future {

public:

 future() noexcept;

 future(future&&) noexcept;

 future& operator=(future&&) noexcept;

 ~future();


 future(future const&) = delete;

 future& operator=(future const&) = delete;


 shared_future share();


 bool valid() const noexcept;


 см. описание get();


 void wait();


 template

 future_status wait_for(

  std::chrono::duration const& relative_time);


 template

 future_status wait_until(

  std::chrono::time_point const& absolute_time);

};

STD::FUTURE
, КОНСТРУКТОР ПО УМОЛЧАНИЮ

Конструирует объект

std::future
, с которым не связан асинхронный результат.

Объявление

future() noexcept;

Результат

Конструирует новый экземпляр

std::future
.

Постусловия

valid()
возвращает
false
.

Исключения

Нет.

STD::FUTURE
, ПЕРЕМЕЩАЮЩИЙ КОНСТРУКТОР

Конструирует объект

std::future
, передавая владение асинхронным результатом от другого объекта
std::future
вновь сконструированному.

Объявление

future(future&& other) noexcept;

Результат

Конструирует новый экземпляр

std::future
путем перемещения содержимого объекта
other
.

Постусловия

Асинхронный результат, ассоциированный с объектом

other
перед вызовом конструктора, ассоциируется с вновь сконструированным объектом
std::future
. С объектом
other
больше не ассоциирован никакой асинхронный результат. Функция
this->valid()
возвращает то же значение, которое возвращала функция
other.valid()
перед вызовом конструктора. Функция
other.valid()
возвращает
false
.

Исключения

Нет.

STD::FUTURE
, ПЕРЕМЕЩАЮЩИЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Передает владение асинхронным результатом, ассоциированным с объектом

std::future
, другому объекту.

Объявление

future(future&& other) noexcept;

Результат

Передает владение асинхронным состоянием между экземплярами

std::future
.

Постусловия

Асинхронный результат, ассоциированный с объектом other перед вызовом оператора, ассоциируется с

*this
. Объект
*this
перестаёт быть владельцем своего прежнего асинхронного состояния (если оно было с ним ассоциировано), и если эта ссылка на асинхронное состояние была последней, то оно уничтожается. Функция
this->valid()
возвращает то же значение, которое возвращала функция
other
,
valid()
перед вызовом оператора. Функция
other.valid()
возвращает
false
.

Исключения

Нет.

STD::FUTURE
, ДЕСТРУКТОР

Уничтожает объект

std::future
.

Объявление

~future();

Результат

Уничтожает

*this
. Если с
*this
была ассоциирована последняя ссылка на асинхронный результат (при условии, что с
*this
вообще что-то ассоциировано), то этот асинхронный результат уничтожается.

Исключения

Нет.

STD::FUTURE::SHARE
, ФУНКЦИЯ-ЧЛЕН

Конструирует новый экземпляр

std::shared_future
и передаёт ему владение асинхронным результатом, ассоциированным с
*this
.

Объявление

shared_future share();

Результат

Эквивалентно

shared_future(std::move(*this))
.

Постусловия

Асинхронный результат, ассоциированный с объектом

*this
перед вызовом
share()
(если с ним что-то было ассоциировано), ассоциируется с вновь сконструированным экземпляром
std::shared_future
. Функция
this->valid()
возвращает
false
.

Исключения

Нет.

STD::FUTURE::VALID
, ФУНКЦИЯ-ЧЛЕН

Проверяет, ассоциирован ли с экземпляром

std::future
асинхронный результат. Объявление

bool valid() const noexcept;

Возвращаемое значение

true
, если с
*this
ассоциирован асинхронный результат, иначе
false
.

Исключения

Нет.

STD::FUTURE::WAIT
, ФУНКЦИЯ-ЧЛЕН

Если состояние, ассоциированное с

*this
, содержит отложенную функцию, то эта функция вызывается. В противном случае ждет, пока будет готов асинхронный результат, ассоциированный с данным экземпляром
std::future
.

Объявление

void wait();

Предусловия

this->valid()
должно возвращать
true
.

Результат

Если ассоциированное состояние содержит отложенную функцию, то вызывает эту функцию и сохраняет возвращенное ей значение или объект-исключение в виде асинхронного результата. В противном случае блокирует поток до момента готовности асинхронного результата, ассоциированного с

*this
.

Исключения

Нет.

STD::FUTURE::WAIT_FOR
, ФУНКЦИЯ-ЧЛЕН

Ждет, когда будет готов асинхронный результат, ассоциированный с данным экземпляром

std::future
, или истечет заданное время.

Объявление

template

future_status wait_for(

 std::chrono::duration const& relative_time);

Предусловия

this->valid()
должно возвращать
true
.

Результат

Если асинхронный результат, ассоциированный с

*this
, содержит отложенную функцию, полученную обращением к
std::async
, и эта функция, еще не начала исполняться, то возвращает управление немедленно без блокирования потока. В противном случае блокирует поток до момента готовности асинхронного результата, ассоциированного с
*this
, или до истечения времени, заданного в аргументе
relative_time
.

Возвращаемое значение

std::future_status::deferred
, если асинхронный результат, ассоциированный с
*this
, содержит отложенную функцию, полученную обращением к
std::async
, и эта функция, еще не начала исполняться.
std::future_status::ready
, если асинхронный результат, ассоциированный с
*this
, готов,
std::future_status::timeout
, если истекло время, заданное в аргументе
relative_time
.

Примечание. Поток может быть заблокирован на время, превышающее указанное. Если возможно, время измеряется по стабильным часам.

Исключения

Нет.

STD::FUTURE::WAIT_UNTIL
, ФУНКЦИЯ-ЧЛЕН

Ждет, когда будет готов асинхронный результат, ассоциированный с данным экземпляром

std::future
, или наступит заданный момент времени.

Объявление

template

future_status wait_until(

std::chrono::time_point const& absolute_time);

Предусловия

this->valid()
должно возвращать
true
.

Результат

Если асинхронный результат, ассоциированный с

*this
, содержит отложенную функцию, полученную обращением к
std::async
, и эта функция, еще не начала исполняться, то возвращает управление немедленно без блокирования потока. В противном случае блокирует поток до момента готовности асинхронного результата, ассоциированного с
*this
, или до момента, когда функция
Clock::now()
вернет время, большее или равное
absolute_time
.

Возвращаемое значение

std::future_status::deferred
, если асинхронный результат, ассоциированный с
*this
, содержит отложенную функцию, полученную обращением к
std::async
, и эта функция, еще не начала исполняться.
std::future_status::ready
, если асинхронный результат, ассоциированный с
*this
, готов,
std::future_status::timeout
, если
Clock::now()
вернула время, большее или равное
absolute_time
.

Примечание. Не дается никаких гарантий относительно того, сколько времени будет блокирован вызывающий поток. Гарантируется лишь, что если функция вернула

std::future_status::timeout
, то значение, возвращенное
Clock::now()
, больше или равно
absolute_time
в точке, где поток разблокировался.

Исключения

Нет.

STD::FUTURE::GET
, ФУНКЦИЯ-ЧЛЕН

Если ассоциированное состояние содержит отложенную функцию, полученную в результате обращения к

std::async
, то вызывает эту функцию и возвращает результат. В противном случае ждет готовности асинхронного результата, ассоциированного с экземпляром
std::future
, а затем либо возвращает сохраненное в нем значение, либо возбуждает сохраненное в нем исключение.

Объявление

void future::get();

R& future::get();

R future::get();

Предусловия

this->valid()
должно возвращать
true
.

Результат

Если состояние, ассоциированное с

*this
, содержит отложенную функцию, то вызывает эту функцию и возвращает результат или возбуждает хранящееся исключение. В противном случае блокирует поток до момента готовности асинхронного результата, ассоциированного с
*this
. Если в результате хранится исключение, возбуждает его, иначе возвращает хранящееся значение.

Возвращаемое значение

Если ассоциированное состояние содержит отложенную функцию, то возвращает результат вызова этой функции. Иначе, если

ResultType
void
, то функция просто возвращает управление. Если
ResultType
R&
для некоторого типа
R
, то возвращает хранящуюся ссылку. Иначе возвращает хранящееся значение.

Исключения

Исключение, возбужденное отложенной функцией или сохраненное в асинхронном результате (если таковое имеется).

Постусловие

this->valid() == false

D.4.2. Шаблон класса
std::shared_future

Шаблон класса

std::shared_future
предоставляет средства для ожидания результата асинхронной операции, начатой в другом потоке, и используется в сочетании с шаблонами классов
std::promise
и
std::packaged_task
и шаблоном функции
std::async
, которая применяется для возврата асинхронного результата. В каждый момент времени ссылаться на один и тот же асинхронный результат могут несколько объектов
std::shared_future
. Экземпляры
std::shared_future
удовлетворяют требованиям концепций
CopyConstructible
и
CopyAssignable
. Разрешается также конструировать объект
std::shared_future
перемещением из объекта
std::future
с тем же самым параметром
ResultType
.

Обращения к данному экземпляру

std::shared_future
не синхронизированы. Поэтому доступ к одному экземпляру
std::shared_future
из разных потоков без внешней синхронизации не безопасен. Однако обращения к ассоциированному состоянию синхронизированы, поэтому несколько потоков могут безопасно обращаться к разным экземплярам
std::shared_future
, которые разделяют одно и то же ассоциированное состояние, без внешней синхронизации.

Определение класса

template

class shared_future {

public:

shared_future() noexcept;

shared_future(future&&) noexcept;


shared_future(shared_future&&) noexcept;

shared_future(shared_future const&);

shared_future& operator=(shared_future const&);

shared_future& operator=(shared_future&&) noexcept;

~shared_future();


bool valid() const noexcept;


см. описание get() const;


void wait() const;


template

future_status wait_for(

std::chrono::duration const& relative_time) const;


template

future_status wait_until(

std::chrono::time_point const& absolute_time)

const;

};

STD::SHARED_FUTURE
, КОНСТРУКТОР ПО УМОЛЧАНИЮ

Конструирует объект

std::shared_future
, с которым не ассоциирован асинхронный результат.

Объявление

shared_future() noexcept;

Результат

Конструирует новый экземпляр

std::shared_future
.

Постусловия

Функция

valid()
вновь сконструированного экземпляра возвращает
false
.

Исключения

Нет.

STD::SHARED_FUTURE
, ПЕРЕМЕЩАЮЩИЙ КОНСТРУКТОР

Конструирует один объект

std::shared_future
из другого, передавая владение асинхронным результатом, ассоциированным со старым объектом
std::shared_future
, вновь сконструированному.

Объявление

shared_future(shared_future&& other) noexcept;

Результат

Конструирует новый экземпляр

std::shared_future
.

Постусловия

Асинхронный результат, ассоциированный с объектом

other
перед вызовом конструктора, ассоциируется с вновь сконструированным объектом
std::shared_future
. С объектом
other
больше не ассоциирован никакой асинхронный результат.

Исключения

Нет.

STD::SHARED_FUTURE
, КОНСТРУКТОР MOVE-FROM-
STD::FUTURE

Конструирует объект

std::shared_future
из объекта
std::future
, передавая владение асинхронным результатом, ассоциированным с объектом
std::future
, вновь сконструированному объекту
std::shared_future
.

Объявление

shared_future(std::future&& other) noexcept;

Результат

Конструирует новый экземпляр

std::shared_future
.

Постусловия

Асинхронный результат, ассоциированный с объектом other перед вызовом конструктора, ассоциируется с вновь сконструированным объектом

std::shared_future
. С объектом
other
больше не ассоциирован никакой асинхронный результат.

Исключения

Нет.

STD::SHARED_FUTURE
, КОПИРУЮЩИЙ КОНСТРУКТОР

Конструирует один объект

std::shared_future
из другого, так что исходный объект и копия ссылаются на асинхронный результат, ассоциированный с исходным объектом
std::shared_future
, если таковой был.

Объявление

shared_future(shared_future const& other);

Результат

Конструирует новый экземпляр

std::shared_future
.

Постусловия

Асинхронный результат, ранее ассоциированный с объектом

other
перед вызовом конструктора, теперь ассоциирован как с вновь сконструированным объектом
std::shared_future
, так и с объектом
other
.

Исключения

Нет.

STD::SHARED_FUTURE
, ДЕСТРУКТОР

Уничтожает объект

std::shared_future
.

Объявление

~shared_future();

Результат

Уничтожает

*this
. Если больше не существует объекта
std::promise
или
std::packaged_task
, ассоциированного с асинхронным результатом, который ассоциирован с
*this
, и это последний экземпляр
std::shared_future
, ассоциированный с этим асинхронным результатом, то асинхронный результат уничтожается.

Исключения

Нет.

STD::SHARED_FUTURE::VALID
, ФУНКЦИЯ-ЧЛЕН

Проверяет, ассоциирован ли асинхронный результат с данным экземпляром

std::shared_future
.

Объявление

bool valid() const noexcept;

Возвращаемое значение

true
, если с
*this
ассоциирован асинхронный результат, иначе
false
.

Исключения

Нет.

STD::SHARED_FUTURE::WAIT
, ФУНКЦИЯ-ЧЛЕН

Если состояние, ассоциированное с

*this
, содержит отложенную функцию, то эта функция вызывается. В противном случае ждет, когда будет готов асинхронный результат, ассоциированный с данным экземпляром
std::shared_future
.

Объявление

void wait() const;

Предусловия

this->valid()
должна возвращать
true
.

Результат

Обращения из нескольких потоков к функциям

get()
и
wait()
экземпляров
std::shared_future
, разделяющих одно и то же ассоциированное состояние, сериализуются. Если ассоциированное состояние содержит отложенную функцию, то первое обращение к
get()
или
wait()
приводит к вызову этой функции и сохранению возвращенного ей значения или возбужденного ей исключения в асинхронном результате. Блокирует поток, пока не будет готов асинхронный результат, ассоциированный с
*this
.

Исключения

Нет.

STD::SHARED_FUTURE::WAIT_FOR
, ФУНКЦИЯ-ЧЛЕН

Ждет, когда будет готов асинхронный результат, ассоциированный с данным экземпляром

std::shared_future
, или истечет заданное время.

Объявление

template

future_status wait_for(

std::chrono::duration const& relative_time) const;

Предусловия

this->valid()
должно возвращать
true
.

Результат

Если асинхронный результат, ассоциированный с

*this
, содержит отложенную функцию, полученную обращением к
std::async
, и эта функция, еще не начала исполняться, то возвращает управление немедленно без блокирования потока. В противном случае блокирует поток до момента готовности асинхронного результата, ассоциированного с
*this
, или до истечения времени, заданного в аргументе
relative_time
.

Возвращаемое значение

std::future_status::deferred
, если асинхронный результат, ассоциированный с
*this
, содержит отложенную функцию, полученную обращением к
std::async
, и эта функция, еще не начала исполняться.
std::future_status::ready
, если асинхронный результат, ассоциированный с
*this
, готов,
std::future_status::timeout
, если истекло время, заданное в аргументе
relative_time
.

Примечание. Поток может быть заблокирован на время, превышающее указанное. Если возможно, время измеряется по стабильным часам.

Исключения

Нет.

STD::SHARED_FUTURE::WAIT_UNTIL
, ФУНКЦИЯ-ЧЛЕН

Ждет, когда будет готов асинхронный результат, ассоциированный с данным экземпляром

std::shared_future
, или наступит заданный момент времени.

Объявление

template

bool wait_until(

std::chrono::time_point const& absolute_time) const;

Предусловия

this->valid()
должно возвращать
true
.

Результат

Если асинхронный результат, ассоциированный с

*this
, содержит отложенную функцию, полученную обращением к
std::async
, и эта функция, еще не начала исполняться, то возвращает управление немедленно без блокирования потока. В противном случае блокирует поток до момента готовности асинхронного результата, ассоциированного с
*this
, или до момента, когда функция
Clock::now()
вернет время, большее или равное
absolute_time
.

Возвращаемое значение

std::future_status::deferred
, если асинхронный результат, ассоциированный с
*this
, содержит отложенную функцию, полученную обращением к
std::async
, и эта функция, еще не начала исполняться.
std::future_status::ready
, если асинхронный результат, ассоциированный с
*this
, готов,
std::future_status::timeout
, если
Clock::now()
вернула время, большее или равное a
bsolute_time
.

Примечание. Не дается никаких гарантий относительно того, сколько времени будет блокирован вызывающий поток. Гарантируется лишь, что если функция вернула

std::future_status::timeout
, то значение, возвращенное
Clock::now()
, больше или равно
absolute_time
в точке, где поток разблокировался.

Исключения

Нет.

STD::SHARED_FUTURE::GET
, ФУНКЦИЯ-ЧЛЕН

Если ассоциированное состояние содержит отложенную функцию, полученную в результате обращения к

std::async
, то вызывает эту функцию и возвращает результат. В противном случае ждет готовности асинхронного результата, ассоциированного с экземпляром
std::shared_future
, а затем либо возвращает сохраненное в нем значение, либо возбуждает сохраненное в нем исключение.

Объявление

void shared_future::get() const;

R& shared_future::get() const;

R const& shared_future::get() const;

Предусловия

this->valid()
должно возвращать
true
.

Результат

Обращения из нескольких потоков к функциям

get()
и
wait()
экземпляров
std::shared_future
, разделяющих одно и то же ассоциированное состояние, сериализуются. Если ассоциированное состояние содержит отложенную функцию, то первое обращение к
get()
или
wait()
приводит к вызову этой функции и сохранению возвращенного ей значения или возбужденного ей исключения в асинхронном результате.

Блокирует поток, пока не будет готов асинхронный результат, ассоциированный с

*this
. Если в результате хранится исключение, возбуждает его, иначе возвращает хранящееся значение.

Возвращаемое значение

Если

ResultType
void
, то функция просто возвращает управление. Если
ResultType
 —
R&
для некоторого типа
R
, то возвращает хранящуюся ссылку. Иначе возвращает константную ссылку на хранящееся значение.

Исключения

Хранящееся исключение, если таковое имеется.

D.4.3. Шаблон класса
std::packaged_task

Шаблон класса

std::packaged_task
упаковывает функцию или другой допускающий вызов объект, так что при вызове функции через экземпляр
std::packaged_task
результат сохраняется в виде асинхронного результата, который может быть получен с помощью объекта
std::future
.

Экземпляры

std::packaged_task
удовлетворяют требованиям концепций
MoveConstructible
и
MoveAssignable
, но не
CopyConstructible
и
CopyAssignable
.

Определение класса

template

class packaged_task; // не определен


template

class packaged_task {

public:

packaged_task() noexcept;

packaged_task(packaged_task&&) noexcept;

~packaged_task();


packaged_task& operator=(packaged_task&&) noexcept;


packaged_task(packaged_task const&) = delete;

packaged_task& operator=(packaged_task const&) = delete;


void swap(packaged_task&) noexcept;


template

explicit packaged_task(Callable&& func);


template

packaged_task(

std::allocator_arg_t, const Allocator&, Callable&&);


bool valid() const noexcept;

std::future get_future();

void operator()(ArgTypes...);

void make_ready_at_thread_exit(ArgTypes...); void reset();

};

STD::PACKAGED_TASK
, КОНСТРУКТОР ПО УМОЛЧАНИЮ

Конструирует объект

std::packaged_task
.

Объявление

packaged_task() noexcept;

Результат

Конструирует экземпляр

std::packaged_task
, с которым не ассоциировала ни задача, ни асинхронный результат.

Исключения

Нет.

STD::PACKAGED_TASK
, КОНСТРУИРОВАНИЕ ИЗ ДОПУСКАЮЩЕГО ВЫЗОВ ОБЪЕКТА

Конструирует экземпляр

std::packaged_task
, с которым ассоциированы задача и асинхронный результат.

Объявление

template

packaged_task(Callable&& func);

Предусловия

Должно быть допустимо выражение

func(args...)
, где каждый элемент
args-i
в списке
args...
должен быть значением соответственного типа
ArgTypes-i
в списке
ArgTypes...
. Возвращаемое значение должно допускать преобразование в тип
ResultType
.

Результат

Конструирует экземпляр

std::packaged_task
, с которым ассоциированы еще не готовый асинхронный результат типа
ResultType
и задача типа
Callable
, полученная копированием
func
.

Исключения

Исключение типа

std::bad_alloc
, если конструктор не смог выделить память для асинхронного результата. Любое исключение, возбуждаемое копирующим или перемещающим конструктором
Callable
.

STD::PACKAGED_TASK
, КОНСТРУИРОВАНИЕ ИЗ ДОПУСКАЮЩЕГО ВЫЗОВ ОБЪЕКТА С РАСПРЕДЕЛИТЕЛЕМ

Конструирует экземпляр

std::packaged_task
, с которым ассоциированы задача и асинхронный результат, применяя предоставленный распределитель для выделения памяти под асинхронный результат и задачу

Объявление

template

packaged_task(

std::allocator_arg_t, Allocator const& alloc, Callable&& func);

Предусловия

Должно быть допустимо выражение

func(args...)
, где каждый элемент
args-i
в списке
args...
должен быть значением соответственного типа
ArgTypes-i
в списке
ArgTypes...
. Возвращаемое значение должно допускать преобразование в тип
ResultType
.

Результат

Конструирует экземпляр

std::packaged_task
, с которым ассоциированы еще не готовый асинхронный результат типа
ResultType
и задача типа
Callable
, полученная копированием
func
. Память под асинхронный результат и задачу выделяется с помощью распределителя
alloc
или его копии.

Исключения

Любое исключение, возбуждаемое распределителем в случае неудачной попытки выделить память под асинхронный результат или задачу. Любое исключение, возбуждаемое копирующим или перемещающим конструктором

Callable
.

STD::PACKAGED_TASK
, ПЕРЕМЕЩАЮЩИЙ КОНСТРУКТОР

Конструирует один объект

std::packaged_task
из другого, передавая владение асинхронным результатом и задачей, ассоциированными с объектом
other
, вновь сконструированному.

Объявление

packaged_task(packaged_task&& other) noexcept;

Результат

Конструирует новый экземпляр

std::packaged_task
.

Постусловия

Асинхронный результат и задача, которые были ассоциированы с объектом

other
до вызова конструктора, ассоциируются со вновь сконструированным объектом
std::packaged_task
. С объектом
other
больше не связан никакой асинхронный результат.

Исключения

Нет.

STD::PACKAGED_TASK
, ПЕРЕМЕЩАЮЩИЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Передает владение ассоциированным асинхронным результатом от одного объекта

std::packaged_task
другому.

Объявление

packaged_task& operator=(packaged_task&& other) noexcept;

Результат

Передает владение асинхронным результатом и задачей, ассоциированными с объектом

other
, объекту
*this
и отбрасывает ранее ассоциированный асинхронный результат, как если бы было выполнено предложение
std::packaged_task(other).swap(*this)
.

Постусловия

Асинхронный результат и задача, которые были ассоциированы с объектом

other
до вызова перемещающего оператора присваивания, ассоциируются с
*this
. С объектом
other
больше не связан никакой асинхронный результат.

Возвращаемое значение

*this

Исключения

Нет.

STD::PACKAGED_TASK::SWAP
, ФУНКЦИЯ-ЧЛЕН

Обменивает владение асинхронными результатами, ассоциированными с двумя объектами

std::packaged_task
.

Объявление

void swap(packaged_task& other) noexcept;

Результат

Обменивает владение асинхронными результатами и задачами, ассоциированными с объектами

other
и
*this
.

Постусловия

Асинхронный результат и задача, которые были ассоциированы с объектом

other
до вызова
swap
(если таковые действительно были), ассоциируются с
*this
. Асинхронный результат и задача, которые были ассоциировать с объектом
*this
до вызова
swap
(если таковые действительно были), ассоциируются с
other
.

Исключения

Нет.

STD::PACKAGED_TASK
, ДЕСТРУКТОР

Уничтожает объект

std::packaged_task
.

Объявление

~packaged_task();

Результат

Уничтожает

*this
. Если с
*this
ассоциирован асинхронный результат и в этом результате не хранится задача или исключение, то результат становится готов, причем в него помещается исключение
std::future_error
с кодом ошибки
std::future_errc::broken_promise
.

Исключения

Нет.

STD::PACKAGED_TASK::GET_FUTURE
, ФУНКЦИЯ-ЧЛЕН

Извлекает экземпляр

std::future
для асинхронного результата, ассоциированного с
*this
.

Объявление

std::future get_future();

Предусловия

С

*this
ассоциирован асинхронный результат.

Возвращаемое значение

Экземпляр

std::future
для асинхронного результата, ассоциированного с
*this
.

Исключения

Исключение типа

std::future_error
с кодом ошибки
std::future_errc::future_already_retrieved
, если объект
std::future
уже был получен для этого асинхронного результата с помощью предшествующего обращения к
get_future()
.

STD::PACKAGED_TASK::RESET
, ФУНКЦИЯ-ЧЛЕН

Ассоциирует экземпляр

std::packaged_task
с новым асинхронным результатом для той же задачи.

Объявление

void reset();

Предусловия

С

*this
ассоциирована асинхронная задача.

Результат

Эквивалентно

*this = packaged_task(std::move(f))
, где
f
― хранимая задача, ассоциированная с
*this
.

Исключения

Исключение типа

std::bad_alloc
, если не удалось выделить память для нового асинхронного результата.

STD::PACKAGED_TASK::VALID
, ФУНКЦИЯ-ЧЛЕН

Проверяет, ассоциированы ли с

*this
задача и асинхронный результат.

Объявление

bool valid() const noexcept;

Возвращаемое значение

true
, если с
*this
ассоциированы задача и асинхронный результат, иначе
false
.

Исключения

Нет.

STD::PACKAGED_TASK::OPERATOR()
, ОПЕРАТОР ВЫЗОВА

Вызывает задачу, ассоциированную с экземпляром

std::packaged_task
, и сохраняет возвращенное ей значение или исключение в ассоциированном асинхронном результате.

Объявление

void operator()(ArgTypes... args);

Предусловия

С

*this
ассоциирована задача.

Результат

Вызывает ассоциированную задачу, как если бы было выполнено предложение

INVOKE(func, args...)
. Если вызов завершается нормально, то сохраняет возвращенное значение в асинхронном результате, ассоциированном с
*this
. Если задача возбуждает исключение, то сохраняет это исключение в асинхронном результате, ассоциированном с
*this
.

Постусловия

Асинхронный результат, ассоциированный с

*this
, готов и содержит значение или исключение. Все потоки, ожидающие асинхронного результата, разблокируются.

Исключения

Исключение типа

std::future_error
с кодом ошибки
std::future_errc::promise_already_satisfied
, если в асинхронном результате уже находится значение или исключение.

Синхронизация

Успешное обращение к оператору вызова синхронизируется-с обращением к

std::future::get()
или
std::shared_future::get()
, которое извлекает хранимое значение или исключение.

STD::PACKAGED_TASK::MAKE_READY_AT_THREAD_EXIT
, ФУНКЦИЯ-ЧЛЕН

Вызывает задачу, ассоциированную с экземпляром

std::packaged_task
, и сохраняет возвращенное ей значение или исключение в ассоциированном асинхронном результате, но не делает этот результат готовым раньше момента завершения потока.

Объявление

void make_ready_at_thread_exit(ArgTypes... args);

Предусловия

С

*this
ассоциирована задача.

Результат

Вызывает ассоциированную задачу, как если бы было выполнено предложение

INVOKE(func, args...)
. Если вызов завершается нормально, то сохраняет возвращенное значение в асинхронном результате, ассоциированном с
*this
. Если задача возбуждает исключение, то сохраняет это исключение в асинхронном результате, ассоциированном с
*this
. Планирует перевод ассоциированного асинхронного результата в состояние готовности в момент завершения потока.

Постусловия

Асинхронный результат, ассоциированный с

*this
, содержит значение или исключение, но не является готовым до завершения текущего потока. Все потоки, ожидающие асинхронного результата, будут разблокированы, когда текущий поток завершится.

Исключения

Исключение типа

std::future_error
с кодом ошибки
std::future_errc::promise_already_satisfied
, если в асинхронном результате уже находится значение или исключение. Исключение типа
std::future_error
с кодом ошибки
std::future_errc::no_state
, если с
*this
не ассоциировано асинхронное состояние. Синхронизация

Завершение потока, в котором была успешно вызвала функция

make_ready_at_thread_exit()
, синхронизируется-с обращением к
std::future::get()
или
std::shared_future::get()
, которое извлекает хранимое значение или исключение.

D.4.4. Шаблон класса
std::promise

Шаблон класса

std::promise
предоставляет средства для установки асинхронного результата, который может быть получен в другом потоке с помощью экземпляра
std::future
.

Параметр

ResultType
— это тип значения, сохраняемого в асинхронном результате.

Объект

std::future
, ассоциированный с асинхронным результатом конкретного экземпляра
std::promise
, можно получить путем обращения к функции-члену
get_future()
. В асинхронный результат записывается либо значение типа
ResultType
функцией-членом
set_value()
, либо исключение функцией-членом
set_exception()
.

Экземпляры

std::promise
удовлетворяют требованиям концепций
MoveConstructible
и
MoveAssignable
, но не
CopyConstructible
или
CopyAssignable
.

Определение класса

template

class promise {

public:

promise();

promise(promise&&) noexcept;

~promise();

promise& operator=(promise&&) noexcept;


template

promise(std::allocator_arg_t, Allocator const&);


promise(promise const&) = delete;

promise& operator=(promise const&) = delete;


void swap(promise&) noexcept;

std::future get_future();


void set_value(see description);

void set_exception(std::exception_ptr p);

};

STD::PROMISE
, КОНСТРУКТОР ПО УМОЛЧАНИЮ

Конструирует объект

std::promise
.

Объявление

promise();

Результат

Конструирует экземпляр

std::promise
, с которым ассоциировал неготовый асинхронный результат типа
ResultType
.

Исключения

Исключение типа

std::bad_alloc
, если конструктор не смог выделить память для асинхронного результата.

STD::PROMISE
, КОНСТРУКТОР С РАСПРЕДЕЛИТЕЛЕМ

Конструирует экземпляр std::promise, применяя предоставленный распределитель для выделения памяти под ассоциированный асинхронный результат.

Объявление

template

promise(std::allocator_arg_t, Allocator const& alloc);

Результат

Конструирует экземпляр

std::promise
, с которым ассоциировал неготовый асинхронный результат типа
ResultType
. Память под асинхронный результат выделяется с помощью распределителя
alloc
.

Исключения

Любое исключение, возбуждаемое распределителем в случае неудачной попытки выделить память под асинхронный результат.

STD::PROMISE
, ПЕРЕМЕЩАЮЩИЙ КОНСТРУКТОР

Конструирует один объект

std::promise
из другого, передавая владение асинхронным результатом от объекта
other
вновь сконструированному.

Объявление

promise(promise&& other) noexcept;

Результат

Конструирует новый экземпляр

std::promise
.

Постусловия

Асинхронный результат, который был ассоциирован с объектом

other
до вызова конструктор, ассоциируется с вновь сконструированным объектом
std::promise
. С объектом
other
больше не ассоциирован никакой асинхронный результат.

Исключения

Нет.

STD::PROMISE
, ПЕРЕМЕЩАЮЩИЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Передает владение асинхронным результатом, ассоциированным с объектом

std::promise
, другому объекту.

Объявление

promise& operator=(promise&& other) noexcept;

Результат

Передает владение асинхронным результатом, ассоциированным с

*this
. Если с
*this
уже был ассоциирован асинхронный результат, то результат становится готов, причем в него помещается исключение
std::future_error
с кодом ошибки
std::future_errc::broken_promise
.

Постусловия

Асинхронный результат, который был ассоциирован с объектом

other
до вызова перемещающего оператора присваивания, ассоциируется с
*this
. С объектом
other
больше не ассоциирован никакой асинхронный результат.

Возвращаемое значение

*this

Исключения

Нет.

STD::PROMISE::SWAP
, ФУНКЦИЯ-ЧЛЕН

Обменивает владение асинхронными результатами, ассоциированными с двумя объектами

std::promise
.

Объявление

void swap(promise& other);

Результат

Обменивает владение асинхронными результатами, ассоциированными с объектами

other
и
*this
.

Постусловия

Асинхронный результат, который был ассоциирован с объектом

other
до вызова
swap
(если таковой действительно был), ассоциируется с
*this
. Асинхронный результат, который был ассоциирован с объектом
*this
до вызова
swap
(если таковой действительно был), ассоциируется с
other
.

Исключения

Нет.

STD::PROMISE
, ДЕСТРУКТОР

Уничтожает объект

std::promise
.

Объявление

~promise();

Результат

Уничтожает

*this
. Если с
*this
ассоциирован асинхронный результат и в этом результате не хранится задача или исключение, то результат становится готов, причем в него помещается исключение
std::future_error
с кодом ошибки
std::future_errc::broken_promise
.

Исключения

Нет.

STD::PROMISE::GET_FUTURE
, ФУНКЦИЯ-ЧЛЕН

Извлекает экземпляр

std::future
для асинхронного результата, ассоциированного с
*this
.

Объявление

std::future get_future();

Предусловия

С

*this
ассоциировал асинхронный результат.

Возвращаемое значение

Экземпляр

std::future
для асинхронного результата, ассоциированного с
*this
.

Исключения

Исключение типа

std::future_error
с кодом ошибки
std::future_errc::future_already_retrieved
, если объект
std::future
уже был получен для этого асинхронного результата с помощью предшествующего обращения к
get_future()
.

STD::PROMISE::SET_VALUE
, ФУНКЦИЯ-ЧЛЕН

Сохраняет значение в асинхронном результате, ассоциированном с

*this
.

Объявление

void promise::set_value();

void promise::set_value(R& r);

void promise::set_value(R const& r);

void promise::set_value(R&& r);

Предусловия

С

*this
ассоциирован асинхронный результат.

Результат

Сохраняет

r
в асинхронном результате, ассоциированном с
*this
, если
ResultType
— не
void
.

Постусловия

Асинхронный результат, ассоциированный с

*this
, готов и содержит значение. Все потоки, ожидающие асинхронного результата, разблокируются.

Исключения

Исключение типа

std::future_error
с кодом ошибки
std::future_errc::promise_already_satisfied
, если в асинхронном результате уже находится значение или исключение. Любое исключение, возбужденное копирующим или перемещающим конструктором
r
.

Синхронизация

Обращения к

set_value()
,
set_value_at_thread_exit()
,
set_exception()
и
set_exception_at_thread_exit()
сериализуются. Успешное обращение к
set_value()
происходит-раньше обращения к функции
std::future::get()
или
std::shared_future::get()
, которая извлекает сохраненное значение.

STD::PROMISE::SET_VALUE_AT_THREAD_EXIT
, ФУНКЦИЯ-ЧЛЕН

Сохраняет значение в асинхронном результате, ассоциированном с

*this
, но не делает этот результат готовым раньше момента завершения потока.

Объявление

void promise::set_value_at_thread_exit();

void promise::set_value_at_thread_exit(R& r);

void promise::set_value_at_thread_exit(R const& r);

void promise::set_value_at_thread_exit(R&& r);

Предусловия

С

*this
ассоциирован асинхронный результат.

Результат

Сохраняет

r
в асинхронном результате, ассоциированном с
*this
, если
ResultType
— не
void
. Помечает, что в асинхронном результате хранится значение. Планирует перевод ассоциированного асинхронного результата в состояние готовности в момент завершения потока.

Постусловия

Асинхронный результат, ассоциированный с

*this
, содержит значение, но не является готовым до завершения текущего потока. Все потоки, ожидающие асинхронного результата, будут разблокированы, когда текущий поток завершится.

Исключения

Исключение типа

std::future_error
с кодом ошибки
std::future_errc::promise_already_satisfied
, если в асинхронном результате уже находится значение или исключение. Любое исключение, возбужденное копирующим или перемещающим конструктором
r
.

Синхронизация

Обращения к

set_value()
,
set_value_at_thread_exit()
,
set_exception()
и
set_exception_at_thread_exit()
сериализуются. Успешное обращение к
set_value()
происходит-раньше обращения к функции
std::future::get()
или
std::shared_future::get()
, которая извлекает сохраненное значение.

STD::PROMISE::SET_EXCEPTION
, ФУНКЦИЯ-ЧЛЕН КЛАССА

Сохраняет исключение в асинхронном результате, ассоциированном с

*this
.

Объявление

void set_exception(std::exception_ptr e);

Предусловия

С

*this
ассоциирован асинхронный результат.
(bool)e
равно
true
.

Результат

Сохраняет

e
в асинхронном результате, ассоциированном с
*this
.

Постусловия

Асинхронный результат, ассоциированный с

*this
, готов и содержит исключение. Все потоки, ожидающие асинхронного результата, разблокируются.

Исключения

Исключение типа

std::future_error
с кодом ошибки
std::future_errc::promise_already_satisfied
, если в асинхронном результате уже находится значение или исключение.

Синхронизация

Обращения к

set_value()
,
set_value_at_thread_exit()
,
set_exception()
и
set_exception_at_thread_exit()
сериализуются. Успешное обращение к
set_value()
происходит-раньше обращения к функции
std::future::get()
или
std::shared_future::get()
, которая извлекает сохраненное исключение.

STD::PROMISE::SET_EXCEPTION_AT_THREAD_EXIT,
ФУНКЦИЯ-ЧЛЕН

Сохраняет исключение в асинхронном результате, ассоциированном с

*this
, но не делает этот результат готовым раньше момента завершения потока.

Объявление

void set_exception_at_thread_exit(std::exception_ptr e);

Предусловия

С

*this
ассоциирован асинхронный результат,
(bool)e
равно
true
.

Результат

Сохраняет

e
в асинхронном результате, ассоциированном с
*this
. Планирует перевод ассоциированного асинхронного результата в состояние готовности в момент завершения потока.

Постусловия

Асинхронный результат, ассоциированный с

*this
, содержит исключение, но не является готовым до завершения текущего потока. Все потоки, ожидающие асинхронного результата, будут разблокированы, когда текущий поток завершится. Исключения

Исключение типа

std::future_error
с кодом ошибки
std::future_errc::promise_already_satisfied
, если в асинхронном результате уже находится значение или исключение.

Синхронизация

Обращения к

set_value()
,
set_value_at_thread_exit()
,
set_exception()
и
set_exception_at_thread_exit()
сериализуются. Успешное обращение к
set_value()
происходит-раньше обращения к функции
std::future::get()
или
std::shared_future::get()
, которая извлекает сохраненное исключение.

D.4.5. Шаблон функции
std::async

Шаблон функции

std::async
дает простой способ выполнить автономную асинхронную задачу с использованием доступного аппаратного параллелизма. Обращение к
std::async
возвращает объект
std::future
, который содержит результат задачи. В зависимости от политики запуска задача выполняется либо асинхронно в отдельном потоке, либо синхронно в том потоке, который вызвал функции-члены
wait()
или
get()
объекта
std::future
.

Объявление

enum class launch {

async, deferred

};


template

future::type>

async(Callable&& func, Args&& ... args);


template

future::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...
.

D.5. Заголовок