Приложение D Справочник по библиотеке С++ Thread Library

D.1. Заголовок
<chrono>

В заголовке

объявлены классы для представления моментов времени, интервалов и часов, которые служат источником объектов
time_point
. В каждом классе часов имеется статическая переменная-член
is_steady
, показывающая, являются ли данные часы стабильными. Стабильными называются часы, которые ходят с постоянной частотой и не допускают подведения. Единственные гарантированно стабильные часы представлены классом
std::chrono::steady_clock
.

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

namespace std {


namespace chrono {


template>

class duration;


template<

 typename Clock,

 typename Duration = typename Clock::duration>

class time_point;


class system_clock;

class steady_clock;

typedef unspecified-clock-type high_resolution_clock;


}


}

D.1.1. Шаблон класса
std::chrono::duration

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

td::chrono::duration
предназначен для представления интервалов. Параметры шаблона
Rep
и
Period
— это соответственно тип данных для хранения значения интервала и конкретизация шаблона класса
std::ratio
, которая задает промежуток времени (в виде долей секунды) между последовательными «тиками». Например,
std::chrono::duration
определяет количество миллисекунд, представимое значением типа
int
, s
td::chrono::duration>
— количество пятидесятых долей секунды, представимое значением типа
short
, а
std::chrono::duration>
— количество минут, представимое значением типа
long long
.

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

template  >

class duration {

public:

 typedef Rep rep;

 typedef Period period;


 constexpr duration() = default;

 ~duration() = default;


 duration(const duration&) = default;

 duration& operator=(const duration&) = default;


 template 

 constexpr explicit duration(const Rep2& r);


 template 

 constexpr duration(const duration& d);


 constexpr rep count() const;

 constexpr duration operator+() const;

 constexpr duration operator-() const;

 duration& operator++();

 duration operator++(int);

 duration& operator--();

 duration operator--(int);

 duration& operator+=(const duration& d);

 duration& operator-=(const duration& d);

 duration& operator*=(const rep& rhs);

 duration& operator/=(const rep& rhs);

 duration& operator%=(const rep& rhs);

 duration& operator%=(const duration& rhs);

 static constexpr duration zero();

 static constexpr duration min();

 static constexpr duration max();

};


template 

constexpr bool operator==(

 const duration& lhs,

 const duration& rhs);


template 

constexpr bool operator !=(

 const duration& lhs,

 const duration& rhs);


template 

constexpr bool operator<(

 const duration& lhs,

 const duration& rhs);


template 

constexpr bool operator<=(

 const duration& lhs,

const duration& rhs);


template 

constexpr bool operator>(

 const duration& lhs,

 const duration& rhs);


template 

constexpr bool operator>=(

 const duration& lhs,

 const duration& rhs);


template 

constexpr ToDuration duration_cast(

 const duration& d);

Требования

Rep
должен быть встроенным числовым типом или определенным пользователем типом со свойствами числа.
Period
должен быть конкретизацией шаблона
std::ratio<>
.


              STD::CHRONO::DURATION::REP, TYPEDEF
            

Это псевдоним типа для хранения числа тиков в значении

duration
.

Объявление

typedef Rep rep;

rep
— тип значения, используемого для хранения внутреннего представления объекта
duration
.


              STD::CHRONO::DURATION::PERIOD, TYPEDEF
            

Это псевдоним типа для конкретизации шаблона класса

std::ratio
, которая задает количество долей секунды, представляемых счетчиком интервала. Например, если
period
— это
std::ratio<1, 50>
, то объект
duration
, для которого
count()
равно N, представляет N пятидесятых долей секунды.

Объявление

typedef Period period;


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

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

std::chrono::duration
со значением по умолчанию.

Объявление

constexpr duration() = default;

Результат

Внутреннее значение

duration
(типа
rep
) инициализируется значением по умолчанию.


              STD::CHRONO::DURATION
            
, КОНВЕРТИРУЮЩИЙ КОНСТРУКТОР ИЗ ЗНАЧЕНИЯ СЧЕТЧИКА

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

std::chrono::duration
с заданным значением счетчика.

Объявление

template 

constexpr explicit duration(const Rep2& r);

Результат

Внутреннее значение объекта

duration
инициализируется значением
static_cast(r)
.

Требования

Этот конструктор участвует в разрешении перегрузки, только если

Rep2
может быть неявно преобразован в
Rep
, и либо
Rep
— тип с плавающей точкой, либо
Rep2
не является типом с плавающей точкой.

Постусловие

this->count() == static_cast(r)


              STD::CHRONO::DURATION
            
, КОНВЕРТИРУЮЩИЙ КОНСТРУКТОР ИЗ ДРУГОГО ЗНАЧЕНИЯ

              STD::CHRONO::DURATION
            

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

std::chrono::duration
, масштабируя значение счетчика другого объекта
std::chrono::duration
.

Объявление

template 

constexpr duration(const duration& d);

Результат

Внутреннее значение объекта

duration
инициализируется значением
duration_cast>(d).count()
.

Требования

Этот конструктор участвует в разрешении перегрузки, только если

Rep
— тип с плавающей точкой, либо
Rep2
не является типом с плавающей точкой, и
Period2
— целое кратное
Period
(то есть
ratio_divide::den == 1
). Это позволяет избежать случайного обрезания (и, значит, потери точности) при сохранении интервала с меньшим периодом в переменной, представляющий интервал с большим периодом.

Постусловие

this->count() == duration_cast>(d).count()

Примеры

duration< int, ratio<1, 1000>> ms(5); ←
5 миллисекунд

duration> s(ms);←┐
Ошибка: нельзя

сохранить мс как

целые секунды

duration> s2(ms);←┐
Правильно:

s2.count() == 0.005

duration> us(ms);←┐
Правильно:

us.count() == 5000


              STD::CHRONO::DURATION::COUNT
            
, ФУНКЦИЯ-ЧЛЕН

Получает значение интервала.

Объявление

constexpr rep count() const;

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

Внутреннее значение объекта

duration
в виде значения типа
rep
.


              STD::CHRONO::DURATION::OPERATOR+
            
, УНАРНЫЙ ОПЕРАТОР ПЛЮС

Пустая операция, возвращает копию

*this
.

Объявление

constexpr duration operator+() const;

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

*this


              STD::CHRONO::DURATION::OPERATOR-
            
, УНАРНЫЙ ОПЕРАТОР МИНУС

Возвращает интервал, в котором значение

count()
противоположно значению
this->count()
.

Объявление

constexpr duration operator-() const;

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

duration(-this->count());


              STD::CHRONO::DURATION::OPERATOR++
            
, ОПЕРАТОР ПРЕДИНКРЕМЕНТА

Инкрементирует внутренний счетчик.

Объявление

duration& operator++();

Результат

++this->internal_count;

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

*this


              STD::CHRONO::DURATION::OPERATOR++
            
, ОПЕРАТОР ПОСТИНКРЕМЕНТА

Инкрементирует внутренний счетчик и возвращает то значение

*this
, которое предшествовало выполнению операции.

Объявление

duration operator++(int);

Результат

duration temp(*this);

++(*this);

return temp;


              STD::CHRONO::DURATION::OPERATOR--
            
, ОПЕРАТОР ПРЕДЕКРЕМЕНТА

Декрементирует внутренний счетчик.

Объявление

duration& operator--();

Результат

--this->internal_count;

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

*this


              STD::CHRONO::DURATION::OPERATOR--
            
, ОПЕРАТОР ПОСТДЕКРЕМЕНТА

Декрементирует внутренний счетчик и возвращает то значение

*this
, которое предшествовало выполнению операции.

Объявление

duration operator--(int);

Результат

duration temp(*this);

--(*this);

return temp;


              STD::CHRONO::DURATION::OPERATOR+=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Прибавляет счетчик другого объекта

duration
к внутреннему счетчику
*this
.

Объявление

duration& operator+=(duration const& other);

Результат

internal_count += other.count();

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

*this


              STD::CHRONO::DURATION::OPERATOR-=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Вычитает счетчик другого объекта

duration
из внутреннего счетчика
*this
.

Объявление

duration& operator-=(duration const& other);

Результат

internal_count-=other.count();

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

*this


              STD::CHRONO::DURATION::OPERATOR*=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Умножает внутренний счетчик

*this
на заданное значение.

Объявление

duration& operator*=(rep const& rhs);

Результат

internal_count*=rhs;

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

*this


              STD::CHRONO::DURATION::OPERATOR/=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Делит внутренний счетчик

*this
на заданное значение.

Объявление

duration& operator/=(rep const& rhs);

Результат

internal_count/=rhs;

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

*this


              STD::CHRONO::DURATION::OPERATOR%=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Записывает во внутренний счетчик

*this
остаток от его деления на заданное значение.

Объявление

duration& operator%=(rep const& rhs);

Результат

internal_count%=rhs;

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

*this


              STD::CHRONO::DURATION::OPERATOR%=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Записывает во внутренний счетчик

*this
остаток от его деления на счетчик в другом объекте
duration
.

Объявление

duration& operator%=(duration const& rhs);

Результат

internal_count %= rhs.count();

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

*this


              STD::CHRONO::DURATION::ZERO
            
, СТАТИЧЕСКАЯ ФУНКЦИЯ-ЧЛЕН

Возвращает объект

duration
, представляющий значение нуль.

Объявление

constexpr duration zero();

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

duration(duration_values::zero());


              STD::CHRONO::DURATION::MIN
            
, СТАТИЧЕСКАЯ ФУНКЦИЯ-ЧЛЕН

Возвращает объект

duration
, представляющий минимально возможное для данной конкретизации значение.

Объявление

constexpr duration min();

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

duration(duration_values::min());


              STD::CHRONO::DURATION::MAX
            
, СТАТИЧЕСКАЯ ФУНКЦИЯ-ЧЛЕН

Возвращает объект

duration
, представляющий максимально возможное для данной конкретизации значение.

Объявление

constexpr duration max();

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

duration(duration_values::max());


              STD::CHRONO::DURATION
            
, ОПЕРАТОР СРАВНЕНИЯ НА РАВЕНСТВО

Сравнивает два объекта

duration
на равенство, даже если они имеют разные представления и (или) периоды.

Объявление

template 

constexpr bool operator==(

 const duration& lhs,

 const duration& rhs);

Требования

Либо для

lhs
определено неявное преобразование в
rhs
, либо наоборот. Если ни одна из частей не может быть неявно преобразована в другую или они являются различными представлениями
duration
, но каждая может быть неявно преобразована в другую, то выражение построено некорректно.

Результат

Если

CommonDuration
— синоним
std::common_type, duration>::type
, to
lhs==rhs
возвращает
CommonDuration(lhs).count() == CommonDuration(rhs).count()
.


              STD::CHRONO::DURATION
            
, ОПЕРАТОР СРАВНЕНИЯ НА НЕРАВЕНСТВО

Сравнивает два объекта

duration
на неравенство, даже если они имеют разные представления и (или) периоды.

Объявление

template 

constexpr bool operator!=(

 const duration& lhs,

 const duration& rhs);

Требования

Либо для

lhs
определено неявное преобразование в
rhs
, либо наоборот. Если ни одна из частей не может быть неявно преобразовала в другую или они являются различными представлениями
duration
, но каждая может быть неявно преобразовала в другую, то выражение построено некорректно.

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

!(lhs == rhs)


              STD::CHRONO::DURATION
            
, ОПЕРАТОР СРАВНЕНИЯ МЕНЬШЕ

Проверяет, что один объект

duration
меньше другого, даже если они имеют разные представления и (или) периоды.

Объявление

template 

constexpr bool operator<(

 const duration& lhs,

 const duration& rhs);

Требования

Либо для

lhs
определено неявное преобразование в
rhs
, либо наоборот. Если ни одна из частей не может быть неявно преобразована в другую или они являются различными представлениями
duration
, по каждая может быть неявно преобразована в другую, то выражение построено некорректно.

Результат

Если

CommonDuration
— синоним
std::common_type< duration< Rep1, Period1>, duration< Rep2, Period2>>::type
, то
lhs
возвращает
CommonDuration(lhs).count() < CommonDuration(rhs).count()
.


              STD::CHRONO::DURATION
            
, ОПЕРАТОР СРАВНЕНИЯ БОЛЬШЕ

Проверяет, что один объект

duration
больше другого, даже если они имеют разные представления и (или) периоды.

Объявление

template 

constexpr bool operator>(

 const duration& lhs,

 const duration& rhs);

Требования

Либо для

lhs
определено неявное преобразование в
rhs
, либо наоборот. Если ни одна из частей не может быть неявно преобразована в другую или они являются различными представлениями
duration
, но каждая может быть неявно преобразована в другую, то выражение построено некорректно.

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

!((rhs


              STD::CHRONO::DURATION
            
, ОПЕРАТОР СРАВНЕНИЯ МЕНЬШЕ ИЛИ РАВНО

Проверяет, что один объект

duration
меньше или равен другому, даже если они имеют разные представления и (или) периоды.

Объявление

template 

constexpr bool operator<=(

 const duration& lhs,

 const duration& rhs);

Требования

Либо для

lhs
определено неявное преобразование в
rhs
, либо наоборот. Если ни одна из частей не может быть неявно преобразовала в другую или они являются различными представлениями
duration
, но каждая может быть неявно преобразована в другую, то выражение построено некорректно.

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

!(rhs>lhs)


              STD::CHRONO::DURATION
            
, ОПЕРАТОР СРАВНЕНИЯ БОЛЬШЕ ИЛИ РАВНО

Проверяет, что один объект

duration
больше или равен другому, даже если они имеют разные представления и (или) периоды.

Объявление

template 

constexpr bool operator>=(

 const duration& lhs,

 const duration& rhs);

Требования

Либо для

lhs
определено неявное преобразование в
rhs
, либо наоборот. Если ни одна из частей не может быть неявно преобразована в другую или они являются различными представлениями
duration
, но каждая может быть неявно преобразована в другую, то выражение построено некорректно.

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

!(lhs


              STD::CHRONO::DURATION_CAST
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Явно преобразует объект

std::chrono::duration
в заданную конкретизацию
std::chrono::duration
.

Объявление

template 

constexpr ToDuration duration_cast(

 const duration& d);

Требования

ToDuration
должен быть конкретизацией
std::chrono::duration
.

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

Значение

d
, преобразованное к типу интервала, заданного параметром
ToDuration
. При выполнении операции минимизируется потеря точности в результате преобразования интервалов с разными масштабами и типами представления.

D.1.2. Шаблон класса
std::chrono::time_point

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

std::chrono::time_point
представляет момент времени, измеренный по конкретным часам. Задается в виде интервала, прошедшего с момента эпохи данных часов. Параметр шаблона
Clock
задает часы (у разных часов должны быть разные типы), а параметр
Duration
— тип для измерения интервала от эпохи, который должен быть конкретизацией шаблона
std::chrono::duration
. По умолчанию
Duration
совпадает с подразумеваемым типом интервала, определенным в
Clock
.

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

template 

class time_point {

public:

 typedef Clock clock;

 typedef Duration duration;

 typedef typename duration::rep rep;

 typedef typename duration::period period;


 time_point();

 explicit time_point(const duration& d);


 template 

 time_point(const time_point& t);


 duration time_since_epoch() const;


 time_point& operator+=(const duration& d);

 time_point& operator-=(const duration& d);


 static constexpr time_point min();

 static constexpr time_point max();

};


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

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

time_point
, представляющий эпоху часов
Clock
; внутренний интервал инициализируется значением
Duration::zero()
.

Объявление

time_point();

Постусловие

Для сконструированного по умолчанию объекта

tp
типа
time_point
имеет место равенство
tp.time_since_epoch() == tp::duration::zero()
.


              STD::CHRONO::TIME_POINT
            
, КОНСТРУКТОР ИЗ ИНТЕРВАЛА

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

time_point
, представляющий заданный интервал от эпохи часов
Clock
.

Объявление

explicit time_point(const duration& d);

Постусловие

Для объекта

tp
типа
time_point
, созданного конструктором
tp(d)
из некоторого интервала
d
, имеет место равенство
tp.time_since_epoch() == d
.


              STD::CHRONO::TIME_POINT
            
, КОНВЕРТИРУЮЩИЙ КОНСТРУКТОР

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

time_point
из другого объекта
time_point
с таким же типом
Clock
, по другим типом
Duration
.

Объявление

template 

time_point(const time_point& t);

Требования

Для типа

Duration2
должно существовать неявное преобразование в тип
Duration
.

Результат

Эквивалентно выражению

time_point(t.time_since_epoch())
.

Значение, возвращенное функцией

t.time_since_epoch()
неявно преобразуется в объект типа
Duration
, который сохраняется в новом объекте типа
time_point
.


              STD::CHRONO::TIME_POINT::TIME_SINCE_EPOCH
            
, ФУНКЦИЯ-ЧЛЕН

Возвращает интервал от эпохи часов для данного объекта типа

time_point
.

Объявление

duration time_since_epoch() const;

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

Значение

duration
, хранящееся в
*this
.


              STD::CHRONO::TIME_POINT::OPERATOR+=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Прибавляет указанный интервал

duration
к значению, хранящемуся в данном объекте
time_point
.

Объявление

time_point& operator+=(const duration& d);

Результат

Прибавляет

d
к внутреннему интервалу
*this
, эквивалентно
this->internal_duration += d
.

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

*this


              STD::CHRONO::TIME_POINT::OPERATOR-=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Вычитает указанный интерфейс

duration
из значения, хранящегося в данном объекте
time_point
.

Объявление

time_point& operator-=(const duration& d);

Результат

Вычитает

d
из внутреннего интервала
*this
, эквивалентно
this->internal_duration -= d
.

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

*this


              STD::CHRONO::TIME_POINT::MIN
            
, СТАТИЧЕСКАЯ ФУНКЦИЯ-ЧЛЕН

Получает объект

time_point
, представляющий минимально возможное для данного типа значение.

Объявление

static constexpr time_point min();

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

time_point(time_point::duration::min())
(см. 11.1.1.15)


              STD::CHRONO::TIME_POINT::MAX,
            
СТАТИЧЕСКАЯ ФУНКЦИЯ-ЧЛЕН

Получает объект

time_point
, представляющий максимально возможное для данного типа значение.

Объявление

static constexpr time_point max();

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

time_point(time_point::duration::max())
(см. 11.1.1.16)

D.1.3. Класс
std::chrono::system_clock

Класс

std::chrono::system_clock
предоставляет средства для получения времени от системных часов реального времени. Текущее время возвращает функция
std::chrono::system_clock::now()
. Объекты класса
std::chrono::system_clock::time_point
можно преобразовывать в тип
time_t
с помощью функции
std::chrono::system_clock::to_time_t()
и получать из этого типа с помощью функции
std::chrono::system_clock::to_time_point()
. Системные часы не стабильны, поэтому последующее обращение к
std::chrono::system_clock::now()
может вернуть момент времени, более ранний, чем при предыдущем обращении (например, если часы операционной системы были подведены вручную или автоматически синхронизировались с внешним источником времени).

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

class system_clock {


public:

 typedef unspecified-integral-type rep;

 typedef std::ratio<unspecified, unspecified> period;

 typedef std::chrono::duration duration;

 typedef std::chrono::time_point time_point;

 static const bool is_steady = unspecified;


 static time_point now() noexcept;


 static time_t to_time_t(const time_point& t) noexcept;

 static time_point from_time_t(time_t t) noexcept;

};


              STD::CHRONO::SYSTEM_CLOCK::REP
            
, TYPEDEF

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

duration
.

Объявление

typedef unspecified-integral-type rep;


              STD::CHRONO::SYSTEM_CLOCK::PERIOD
            
, TYPEDEF

Псевдоним типа для конкретизации шаблонного класса

std::ratio
, которая определяет наименьшее число секунд (или долей секунды) между различающимися значениями
duration
или
time_point
. Псевдоним
period
определяет точность часов, а не частоту тактов.

Объявление

typedef std::ratio<unspecified, unspecified> period;


              STD::CHRONO::SYSTEM_CLOCK::DURATION
            
, TYPEDEF

Конкретизация шаблонного класса

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

Объявление

typedef std::chrono::duration<

 std::chrono::system_clock::rep,

 std::chrono::system_clock::period> duration;


              STD::CHRONO::SYSTEM_CLOCK::TIME_POINT
            
, TYPEDEF

Конкретизация шаблонного класса

std::chrono::time_point
, в которой могут храниться моменты времени, полученные от системных часов реального времени.

Объявление

typedef std::chrono::time_point time_point;


              STD::CHRONO::SYSTEM_CLOCK::NOW
            
, СТАТИЧЕСКАЯ ФУНКЦИЯ-ЧЛЕН

Получает текущее время от системных часов реального времени.

Объявление

time_point now() noexcept;

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

Экземпляр

time_point
, представляющий текущее время по системным часам реального времени.

Исключения

Возбуждает исключение

std::system_error
в случае ошибки.

STD::CHRONO::SYSTEM_CLOCK::TO_TIME_T
, СТАТИЧЕСКАЯ ФУНКЦИЯ-ЧЛЕН

Преобразует объект типа

time_point
в объект типа
time_t
.

Объявление

time_t to_time_t(time_point const& t) noexcept;

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

Экземпляр

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

Исключения

Возбуждает исключение

std::system_error
в случае ошибки.


              STD::CHRONO::SYSТЕМ_CLOCK::FROM_TIME_T
            
, СТАТИЧЕСКАЯ ФУНКЦИЯ-ЧЛЕН

Преобразует объект типа

time_t
в объект типа
time_point
.

Объявление

time_point from_time_t(time_t const& t) noexcept;

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

Экземпляр

time_point
, представляющий тот же момент времени, что и
t
.

Исключения

Возбуждает исключение

std::system_error
в случае ошибки.

D.1.4. Класс
std::chrono::steady_clock

Класс

std::chrono::steady_clock
предоставляет доступ к системным стабильным часам. Текущее время возвращает функция
std::chrono::steady_clock::now()
. He существует фиксированного соотношения между значениями, возвращаемыми
std::chrono::steady_clock::now()
и показаниями часов реального времени. Стабильные часы не могут «идти в обратную сторону», поэтому если некое обращение к функции
std::chrono::steady_clock::now()
происходит-раньше другого обращения к ней же, то второе обращение должно вернуть момент времени, больший или равным первому. Часы ходят с частотой, настолько близкой к постоянной, насколько это возможно.

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

class steady_clock {

public:

 typedef unspecified-integral-type rep;

 typedef std::ratio<

  unspecified, unspecified> period;

 typedef std::chrono::duration duration;

 typedef std::chrono::time_point

 time_point;

 static const bool is_steady = true;


 static time_point now() noexcept;

};


              STD::CHRONO::STEADY_CLOCK::REP
            
, TYPEDEF

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

duration
.

Объявление

typedef unspecified-integral-type rep;


              STD::CHRONO::STEADY_CLOCK::PERIOD
            
, TYPEDEF

Псевдоним типа для конкретизации шаблонного класса

std::ratio
, которая определяет наименьшее число секунд (или долей секунды) между различающимися значениями
duration
или
time_point
. Псевдоним
period
определяет точность часов, а не частоту тактов.

Объявление

typedef std::ratio<unspecified, unspecified> period;


              STD::CHRONO::STEADY_CLOCK::DURATION
            
, TYPEDEF

Конкретизация шаблонного класса

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

Объявление

typedef std::chrono::duration<

 std::chrono::steady_clock::rep,

 std::chrono::steady_clock::period> duration;


              STD::CHRONO::STEADY_CLOCK::TIME_POINT
            
, TYPEDEF

Конкретизация шаблонного класса

std::chrono::time_point
, в которой могут храниться моменты времени, полученные от системных стабильных часов.

Объявление

typedef std::chrono::time_point

time_point;


              STD::CHRONO::STEADY_CLOCK::NOW
            
, СТАТИЧЕСКАЯ ФУНКЦИЯ-ЧЛЕН

Получает текущее время от системных стабильных часов.

Объявление

time_point now() noexcept;

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

Экземпляр

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

Исключения

Возбуждает исключение

std::system_error
в случае ошибки.

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

Если одно обращение к

std::chrono::steady_clock::now()
происходит-раньше другого, то момент времени
time_point
, возвращенный при первом обращении, меньше или равен моменту времени
time_point
, возвращенному при втором обращении.

D.1.5. Псевдоним типа
std::chrono::high_resolution_clock

Класс

std::chrono::high_resolution_clock
предоставляет доступ к системным часам максимально высокого разрешения. Как и для всех остальных часов, текущее время можно получить от функции
std::chrono::high_resolution_clock::now()
. Имя
std::chrono::high_resolution_clock
может быть псевдонимом класса
std::chrono::system_clock
или класса
std::chrono::steady_clock
, либо отдельным типом.

Хотя тип

std::chrono::high_resolution_clock
дает самое высокое разрешение среди всех входящих в библиотеку часов, обращение к функции
std::chrono::high_resolution_clock::now()
все же занимает конечное время. Поэтому, пытаясь хронометрировать очень короткие операции, учитывайте накладные расходы на вызов этой функции.

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

class high_resolution_clock {

public:

 typedef unspecified-integral-type rep;

 typedef std::ratio<

  unspecified, unspecified> period;

 typedef std::chrono::duration duration;

 typedef std::chrono::time_point<

  unspecified> time_point;

 static const bool is_steady = unspecified;


 static time_point now() noexcept;

};

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

Заголовок

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

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

namespace std {

enum class cv_status { timeout, no_timeout };


class condition_variable;

class condition_variable_any;

}

D.2.1. Класс
std::condition_variable

Класс

std::condition_variable
позволяет потоку ждать выполнения условия.

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

CopyAssignable
,
CopyConstructible
,
MoveAssignable
,
MoveConstructible
.

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

class condition_variable {

public:

 condition_variable();

 ~condition_variable();


 condition_variable(condition_variable const&) = delete;

 condition_variable& operator=(

  condition_variable const&) = delete;


 void notify_one() noexcept;

 void notify_all() noexcept;


 void wait(std::unique_lock& lock);


 template 

 void wait(std::unique_lock& lock, Predicate pred);


 template 

 cv_status wait_until(

  std::unique_lock& lock,

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


 template 

 bool wait_until(

  std::unique_lock& lock,

  const std::chrono::time_point& absolute_time,

  Predicate pred);


 template 

 cv_status wait_for(

  std::unique_lock& lock,

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


 template 

 bool wait_for(

  std::unique_lock& lock,

  const std::chrono::duration& relative_time,

  Predicate pred);

};


void notify_all_at_thread_exit(

 condition_variable&, unique_lock);


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

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

std::condition_variable
.

Объявление

condition_variable();

Результат

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

std::condition_variable
.

Исключения

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

std::system_error
, если сконструировать условную переменную не получилось.


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

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

std::condition_variable
.

Объявление

~condition_variable();

Предусловия

Не существует потоков, заблокированных по

*this
в обращениях к
wait()
,
wait_for()
или
wait_until()
.

Результат

Уничтожает

*this
.

Исключения

Нет.


              STD::CONDITION_VARIABLE::NOTIFY_ONE
            
, ФУНКЦИЯ-ЧЛЕН

Пробуждает один из потоков, ожидающих

std::condition_variable
.

Объявление

void notify_one() noexcept;

Результат

Пробуждает один из потоков, ожидающих

*this
, в точке вызова. Если таких потоков нет, функция не имеет никакого эффекта.

Исключения

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

std::system_error
, если действие не выполнено.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


              STD::CONDITION_VARIABLE::NOTIFY_ALL
            
, ФУНКЦИЯ-ЧЛЕН

Пробуждает все потоки, ожидающие

std::condition_variable
.

Объявление

void notify_all() noexcept;

Результат

Пробуждает все потоки, ожидающие

*this
, в точке вызова. Если таких потоков нет, функция не имеет никакого эффекта.

Исключения

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

std::system_error
, если действие не выполнено.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


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

Ожидает, пока условная переменная

std::condition_variable
не получит сигнал в результате обращения к
notify_one()
или
notify_all()
либо не произойдёт ложное пробуждение.

Объявление

void wait(std::unique_lock& lock);

Предусловия

Значение

lock.owns_lock()
равно
true
, и блокировкой владеет вызывающий поток.

Результат

Атомарно разблокирует предоставленный объект

lock
и блокирует поток, пока он не будет разбужен обращением к
notify_one()
или
notify_all()
из другого потока либо не произойдёт ложное пробуждение. Перед возвратом управления из
wait()
объект
lock
снова блокируется.

Исключения

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

std::system_error
, если действие не выполнено. Если объект
lock
был разблокирован при обращении к
wait()
, он снова блокируется при выходе из нее, даже если выход произошёл в результате исключения.

Примечание. Ложное пробуждение означает, что поток, вызвавший

wait()
, может быть разбужен, даже если ни один другой поток не обращался к
notify_one()
или
notify_all()
. Поэтому рекомендуется использовать перегруженный вариант
wait()
, который принимает предикат. Если это нежелательно, то рекомендуется вызывать
wait()
в цикле, где проверяется предикат, ассоциированный с условной переменной.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


              STD::CONDITION_VARIABLE::WAIT
            
, ПЕРЕГРУЖЕННАЯ ФУНКЦИЯ-ЧЛЕН, ПРИНИМАЮЩАЯ ПРЕДИКАТ

Ожидает, пока условная переменная

std::condition_variable
не получит сигнал в результате обращения к
notify_one()
или
notify_all()
и при этом предикат равен
true
.

Объявление

template

void wait(std::unique_lock& lock, Predicate pred);

Предусловия

Выражение

pred()
должно быть допустимо и возвращать значение, преобразуемое в тип
bool
. Значение
lock.owns_lock()
должно быть равно
true
, и владельцем блокировки
lock
должен быть поток, вызвавший
wait()
.

Результат

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

while (!pred()) {

 wait(lock);

}

Исключения

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

pred
, или
std::system_error
, если действие не выполнено.

Примечание. Возможность ложного пробуждения означает, что функция

pred
может вызываться несколько раз (сколько именно, не определено). При любом вызове
pred
мьютекс, на который ссылается объект
lock
, гарантированно будет захвачен, и функция вернет управление тогда и только тогда, когда результатом вычисления
(bool)pred()
является
true
.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


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

Ожидает, пока условная переменная

std::condition_variable
не получит сигнал в результате обращения к
notify_one()
или
notify_all()
, либо не истечет таймаут, либо не произойдёт ложное пробуждение.

Объявление

template

cv_status wait_for(

std::unique_lock& lock,

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

Предусловия

Значение

lock.owns_lock()
равно
true
, и блокировкой владеет вызывающий поток.

Результат

Атомарно разблокирует предоставленный объект

lock
и блокирует поток, пока он не будет разбужен обращением к
notify_one()
или
notify_all()
из другого потока, либо не истечет таймаут, заданный аргументом
relative_time
, либо не произойдёт ложное пробуждение. Перед возвратом управления из
wait_for()
объект
lock
снова блокируется.

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

std::cv_status::no_timeout
, если поток был разбужен в результате обращения к
notify_one()
или
notify_all()
либо ложного пробуждения. В противном случае
std::cv_status::timeout
.

Исключения

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

std::system_error
, если действие не выполнено. Если объект
lock
был разблокирован при обращении к
wait_for()
, он снова блокируется при выходе из нее, даже если выход произошёл в результате исключения.

Примечание. Ложное пробуждение означает, что поток, вызвавший

wait_for()
, может быть разбужен, даже если ни один другой поток не обращался к
notify_one()
или
notify_all()
. Поэтому рекомендуется использовать перегруженный вариант
wait_for()
, который принимает предикат. Если это нежелательно, то рекомендуется вызывать
wait_for()
в цикле, где проверяется предикат, ассоциированный с условной переменной. При этом необходимо следить, не истек ли таймаут. Во многих случаях предпочтительнее использовать функцию
wait_until()
. Поток может быть блокирован дольше, чем указано. Если возможно, истекшее время измеряется по стабильным часам.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


              STD::CONDITION_VARIABLE::WAIT_FOR
            
, ПЕРЕГРУЖЕННАЯ ФУНКЦИЯ-ЧЛЕН, ПРИНИМАЮЩАЯ ПРЕДИКАТ

Ожидает, пока условная переменная

std::condition_variable
не получит сигнал в результате обращения к
notify_one()
или
notify_all()
и при этом предикат равен
true
, либо не истечет указанный таймаут.

Объявление

template

bool wait_for(

 std::unique_lock& lock,

 std::chrono::duration const& relative_time,

 Predicate pred);

Предусловия

Выражение

pred()
должно быть допустимо и возвращать значение, преобразуемое в тип
bool
. Значение
lock.owns_lock()
должно быть равно
true
, и владельцем блокировки
lock
должен быть поток, вызвавший
wait_for()
.

Результат

Эквивалентно следующему коду:

internal_clock::time_point end =

 internal_clock::now() + relative_time;

while (!pred()) {

 std::chrono::duration remaining_time =

  end-internal_clock::now();

 if (wait_for(lock, remaining_time) == std::cv_status::timeout)

  return pred();

}

return true;

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

true
, если последнее обращение к
pred()
вернуло
true
;
false
, если истекло время, заданное в аргументе
relative_time
и обращение к
pred()
вернуло
false
.

Примечание. Возможность ложного пробуждения означает, что функция

pred
может вызываться несколько раз (сколько именно, не определено). При любом вызове
pred
мьютекс, на который ссылается объект
lock
, гарантированно будет захвачен, и функция вернет управление тогда и только тогда, когда результатом вычисления
(bool)pred()
является
true
или истекло время, заданное в аргументе
relative_time
. Поток может быть блокирован дольше, чем указано. Если возможно, истекшее время измеряется по стабильным часам.

Исключения

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

pred
, или
std::system_error
, если действие не выполнено.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


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

Ожидает, пока условная переменная

std::condition_variable
не получит сигнал в результате обращения к
notify_one()
или
notify_all()
либо не будет достигнут указанный момент времени, либо не произойдёт ложное пробуждение.

Объявление

template

cv_status wait_until(

 std::unique_lock& lock,

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

Предусловия

Значение

lock.owns_lock()
равно
true
, и владельцем блокировки
lock
является вызывающий поток.

Результат

Атомарно разблокирует предоставленный объект

lock
и блокирует поток, пока он не будет разбужен обращением к
notify_one()
или
notify_all()
из другого потока, либо функция
Clock::now()
не вернет время, большее или равное
absolute_time
, либо не произойдёт ложное пробуждение. Перед возвратом управления из
wait_until()
объект
lock
снова блокируется.

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

std::cv_status::no_timeout
, если поток был разбужен в результате обращения к
notify_one()
или
notify_all()
либо ложного пробуждения. В противном случае
std::cv_status::timeout
.

Исключения

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

std::system_error
, если действие не выполнено. Если объект
lock
был разблокирован при обращении к
wait_for()
, он снова блокируется при выходе из нее, даже если выход произошёл в результате исключения.

Примечание. Ложное пробуждение означает, что поток, вызвавший

wait_until()
, может быть разбужен, даже если ни один другой поток не обращался к
notify_one()
или
notify_all()
. Поэтому рекомендуется использовать перегруженный вариант
wait_until()
, который принимает предикат. Если это нежелательно, то рекомендуется вызывать
wait_until()
в цикле, где проверяется предикат, ассоциированный с условной переменной. Не дается никаких гарантий относительно того, сколько времени будет блокирован вызывающий поток. Гарантируется лишь, что если функция вернула
false
, то значение, возвращенное
Clock::now()
, больше или равно
absolute_time
в точке, где поток разблокировался.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


              STD::CONDITION_VARIABLE::WAIT_UNTIL
            
, ПЕРЕГРУЖЕННАЯ ФУНКЦИЯ-ЧЛЕН, ПРИНИМАЮЩАЯ ПРЕДИКАТ

Ожидает, пока условная переменная

std::condition_variable
не получит сигнал в результате обращения к
notify_one()
или
notify_all()
, и при этом предикат равен
true
, либо не будет достигнут указанный момент времени.

Объявление

template

bool wait_until(

 std::unique_lock& lock,

 std::chrono::time_point const& absolute_time,

 Predicate pred);

Предусловия

Выражение

pred()
должно быть допустимо и возвращать значение, преобразуемое в тип
bool
. Значение
lock.owns_lock()
должно быть равно
true
, и владельцем блокировки
lock
должен быть поток, вызвавший
wait_until()
.

Результат

Эквивалентно следующему коду:

while (!pred()) {

 if (wait_until(lock, absolute_time) == std::cv_status::timeout)

  return pred();

}

return true;

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

true
, если последнее обращение к
pred()
вернуло
true
;
false
, если функция
Clock::now()
вернула время, большее или равное
absolute_time
, и обращение к
pred()
вернуло
false
.

Примечание. Возможность ложного пробуждения означает, что функция

pred
может вызываться несколько раз (сколько именно, не определено). При любом вызове
pred
мьютекс, на который ссылается объект
lock
, гарантированно будет захвачен, и функция вернет управление тогда и только тогда, когда результатом вычисления
(bool)pred()
является
true
или функция
Clock::now()
вернула время, больше или равное
absolute_time
. Не дается никаких гарантий относительно того, сколько времени будет блокирован вызывающий поток. Гарантируется лишь, что если функция вернула
false
, то значение, возвращенное
Clock::now()
, больше или равно
absolute_time
в точке, где поток разблокировался.

Исключения

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

pred
, или
std::system_error
, если действие не выполнено.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


              STD::NOTIFY_ALL_AT_THREAD_EXIT
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Пробуждает все потоки, ожидающие

std::condition_variable
, при завершении текущего потока.

Объявление

void notify_all_at_thread_exit(

 condition_variable& cv, unique_lock lk);

Предусловия

Значение

lock.owns_lock()
равно
true
, и владельцем блокировки
lock
является вызывающий поток. Функция
lk.mutex()
должна возвращать такое же значение, как для любого объекта блокировки, передаваемого функциям-членам
wait()
,
wait_for()
или
wait_until()
объекта
cv
из одновременно ожидающих потоков.

Результат

Передает владение мьютексом, захваченным

lk
, внутреннему объекту и планирует отправку уведомления условной переменной
cv
при завершении вызывающего потока. Уведомление эквивалентно выполнению следующего кода:

lk.unlock();

cv.notify_all();

Исключения

Возбуждает исключение

std::system_error
, если действие не выполнено.

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

Пользователь должен следить за тем, чтобы ожидающий поток не сделал ошибочного предположения о том, что в момент его пробуждения данный поток уже завершен, — в частности, из-за возможности ложного пробуждения. Для этого можно проверять в ожидающем потоке предикат, который может быть сделан истинным только уведомляющим потоком, причём это должно делаться под защитой мьютекса, который не освобождается до вызова

notify_all_at_thread_exit
.

D.2.2. Класс
std::condition_variable_any

Класс

std::condition_variable_any
позволяет потоку ждать выполнения условия. Если объект
std::condition_variable
можно использовать только с блокировкой типа
std::unique_lock
, то
std::condition_variable_any
допустимо использовать с блокировкой любого типа, удовлетворяющего требованиям концепции
Lockable
.

Экземпляры

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

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

class condition_variable_any {

public:

 condition_variable_any();

 ~condition_variable_any();


 condition_variable_any(

  condition_variable_any const&) = delete;

 condition_variable_any& operator=(

  condition_variable_any const&) = delete;


 void notify_one() noexcept;

 void notify_all() noexcept;


 template

 void wait(Lockable& lock);


 template 

 void wait(Lockable& lock, Predicate pred);


 template 

 std::cv_status wait_until(

  Lockable& lock,

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


 template <

  typename Lockable, typename Clock,

  typename Duration, typename Predicate>

 bool wait_until(

  Lockable& lock,

  const std::chrono::time_point& absolute_time,

  Predicate pred);


 template 

 std::cv_status wait_for(

  Lockable& lock,

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


 template <

  typename Lockable, typename Rep,

  typename Period, typename Predicate>

 bool wait_for(

  Lockable& lock,

  const std::chrono::duration& relative_time,

  Predicate pred);

};


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

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

std::condition_variable_any
.

Объявление

condition_variable_any();

Результат

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

std::condition_variable_any
.

Исключения

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

std::system_error
, если сконструировать условную переменную не получилось.


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

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

td::condition_variable_any
.

Объявление

~condition_variable_any();

Предусловия

Не существует потоков, заблокированных по

*this
в обращениях к
wait()
,
wait_for()
или
wait_until()
.

Результат

Уничтожает

*this
.

Исключения

Нет.


              STD::CONDITION_VARIABLE_ANY::NOTIFY_ONE
            
, ФУНКЦИЯ-ЧЛЕН

Пробуждает один из потоков, ожидающих

std::condition_variable_any
.

Объявление

void notify_one() noexcept;

Результат

Пробуждает один из потоков, ожидающих

*this
, в точке вызова. Если таких потоков нет, функция не имеет никакого эффекта.

Исключения

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

std::system_error
, если действие не выполнено.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable_any
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


              STD::CONDITION_VARIABLE_ANY::NOTIFY_ALL
            
, ФУНКЦИЯ-ЧЛЕН

Пробуждает все потоки, ожидающие

std::condition_variable_any
.

Объявление

void notify_all() noexcept;

Результат

Пробуждает все потоки, ожидающие

*this
, в точке вызова. Если таких потоков нет, функция не имеет никакого эффекта.

Исключения

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

std::system_error
, если действие не выполнено.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable_any
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


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

Ожидает, пока условная переменная

std::condition_variable_any
не получит сигнал в результате обращения к
notify_one()
или
notify_all()
либо не произойдёт ложное пробуждение.

Объявление

template

void wait(Lockable& lock);

Предусловия

Тип

Lockable
удовлетворяет требованиям концепции
Lockable
и
lock
владеет блокировкой.

Результат

Атомарно разблокирует предоставленный объект

lock
и блокирует поток, пока он не будет разбужен обращением к
notify_one()
или
notify_all()
из другого потока либо не произойдёт ложное пробуждение. Перед возвратом управления из
wait()
объект
lock
снова блокируется.

Исключения

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

std::system_error
, если действие не выполнено. Если объект
lock
был разблокирован при обращении к
wait()
, он снова блокируется при выходе из нее, даже если выход произошёл в результате исключения.

Примечание. Ложное пробуждение означает, что поток, вызвавший

wait()
, может быть разбужен, даже если ни один другой поток не обращался к
notify_one()
или
notify_all()
. Поэтому рекомендуется использовать перегруженный вариант
wait()
, который принимает предикат. Если это нежелательно, то рекомендуется вызывать
wait()
в цикле, где проверяется предикат, ассоциированный с условной переменной.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable_any
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


              STD::CONDITION_VARIABLE_ANY::WAIT
            
, ПЕРЕГРУЖЕННАЯ ФУНКЦИЯ-ЧЛЕН, ПРИНИМАЮЩАЯ ПРЕДИКАТ

Ожидает, пока условная переменная

std::condition_variable_any
получит сигнал в результате обращения к
notify_one()
или
notify_all()
и при этом предикат равен
true
.

Объявление

template

void wait(Lockable& lock, Predicate pred);

Предусловия

Выражение

pred()
должно быть допустимо и возвращать значение, преобразуемое в тип
bool
. Тип
Lockable
удовлетворяет требованиям концепции
Lockable
и
lock
владеет блокировкой.

Результат

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

while (!pred()) {

 wait(lock);

}

Исключения

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

pred
, или
std::system_error
, если действие не выполнено.

Примечание. Возможность ложного пробуждения означает, что функция

pred
может вызываться несколько раз (сколько именно, не определено). При любом вызове
pred
мьютекс, на который ссылается объект
lock
, гарантированно будет захвачен, и функция вернет управление тогда и только тогда, когда результатом вычисления
(bool)pred()
является
true
.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable_any
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


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

Ожидает, пока условная переменная

std::condition_variable_any
получит сигнал в результате обращения к
notify_one()
или
notify_all()
, либо истечет таймаут, либо произойдёт ложное пробуждение.

Объявление

template

std::cv_status wait_for(

 Lockable& lock,

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

Предусловия

Тип

Lockable
удовлетворяет требованиям концепции
Lockable
и
lock
владеет блокировкой.

Результат

Атомарно разблокирует предоставленный объект

lock
и блокирует поток, пока он не будет разбужен обращением к
notify_one()
или
notify_all()
из другого потока, либо не истечет таймаут, заданный аргументом
relative_time
, либо не произойдёт ложное пробуждение. Перед возвратом управления из
wait_for()
объект
lock
снова блокируется.

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

std::cv_status::no_timeout
, если поток был разбужен в результате обращения к
notify_one()
или
notify_all()
либо ложного пробуждения. В противном случае
std::cv_status::timeout
.

Исключения

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

std::system_error
, если действие не выполнено. Если объект
lock
был разблокирован при обращении к
wait_for()
, он снова блокируется при выходе из нее, даже если выход произошёл в результате исключения.

Примечание. Ложное пробуждение означает, что поток, вызвавший

wait_for()
, может быть разбужен, даже если ни один другой поток не обращался к
notify_one()
или
notify_all()
. Поэтому рекомендуется использовать перегруженный вариант
wait_for()
, который принимает предикат. Если это нежелательно, то рекомендуется вызывать
wait_for()
в цикле, где проверяется предикат, ассоциированный с условной переменной. При этом необходимо следить, не истек ли таймаут. Во многих случаях предпочтительнее использовать функцию
wait_until()
. Поток может быть блокирован дольше, чем указано. Если возможно, истекшее время измеряется по стабильным часам.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable_any
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


              STD::CONDITION_VARIABLE_ANY::WAIT_FOR
            
, ПЕРЕГРУЖЕННАЯ ФУНКЦИЯ-ЧЛЕН, ПРИНИМАЮЩАЯ ПРЕДИКАТ

Ожидает, пока условная переменная

std::condition_variable_any
получит сигнал в результате обращения к
notify_one()
или
notify_all()
и при этом предикат равен
true
, либо истечет указанный таймаут.

Объявление

template

     typename Period, typename Predicate>

bool wait_for(

 Lockable& lock,

 std::chrono::duration const& relative_time,

 Predicate pred);

Предусловия

Выражение

pred()
должно быть допустимо и возвращать значение, преобразуемое в тип
bool
. Тип
Lockable
удовлетворяет требованиям концепции
Lockable
и
lock
владеет блокировкой.

Результат

Эквивалентно следующему коду:

internal_clock::time_point end

 = internal_clock::now() + relative_time;

while (!pred()) {

 std::chrono::duration remaining_time =

  end-internal_clock::now();

 if (wait_for(lock, remaining_time) == std::cv_status::timeout)

  return pred();

}

return true;

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

true
, если последнее обращение к
pred()
вернуло
true
;
false
, если истекло время, заданное в аргументе
relative_time
и обращение к
pred()
вернуло
false
.

Примечание. Возможность ложного пробуждения означает, что функция

pred
может вызываться несколько раз (сколько именно, не определено). При любом вызове
pred
мьютекс, на который ссылается объект
lock
, гарантированно будет захвачен, и функция вернет управление тогда и только тогда, когда результатом вычисления
(bool)pred()
является
true
или истекло время, заданное в аргументе
relative_time
. Поток может быть блокирован дольше, чем указано. Если возможно, истекшее время измеряется по стабильным часам.

Исключения

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

pred
, или
std::system_error
, если действие не выполнено.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable_any
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


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

Ожидает, пока условная переменная

std::condition_variable_any
получит сигнал в результате обращения к
notify_one()
или
notify_all()
либо будет достигнут указанный момент времени, либо произойдёт ложное пробуждение.

Объявление

template

std::cv_status wait_until(

 Lockable& lock,

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

Предусловия

Тип

Lockable
удовлетворяет требованиям концепции
Lockable
и
lock
владеет блокировкой.

Результат

Атомарно разблокирует предоставленный объект

lock
и блокирует поток, пока он не будет разбужен обращением к
notify_one()
или
notify_all()
из другого потока, либо функция
Clock::now()
не вернет время, большее или равное
absolute_time
, либо не произойдёт ложное пробуждение. Перед возвратом управления из
wait_until()
объект
lock
снова блокируется.

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

std::cv_status::no_timeout
, если поток был разбужен в результате обращения к
notify_one()
или
notify_all()
либо ложного пробуждения. В противном случае
std::cv_status::timeout
.

Исключения

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

std::system_error
, если действие не выполнено. Если объект
lock
был разблокирован при обращении к
wait_for()
, он снова блокируется при выходе из нее, даже если выход произошёл в результате исключения.

Примечание. Ложное пробуждение означает, что поток, вызвавший

wait_until()
, может быть разбужен, даже если ни один другой поток не обращался к
notify_one()
или
notify_all()
. Поэтому рекомендуется использовать перегруженный вариант
wait_until()
, который принимает предикат. Если это нежелательно, то рекомендуется вызывать
wait_until()
в цикле, где проверяется предикат, ассоциированный с условной переменной. Не дается никаких гарантий относительно того, сколько времени будет блокирован вызывающий поток. Гарантируется лишь, что если функция вернула
false
, то значение, возвращенное
Clock::now()
, больше или равно
absolute_time
в точке, где поток разблокировался.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable_any
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.


              STD::CONDITION_VARIABLE_ANY::WAIT_UNTIL
            
, ПЕРЕГРУЖЕННАЯ ФУНКЦИЯ-ЧЛЕН, ПРИНИМАЮЩАЯ ПРЕДИКАТ

Ожидает, пока условная переменная

std::condition_variable_any
но лучит сигнал в результате обращения к
notify_one()
или
notify_all()
, и при этом предикат равен
true
, либо будет достигнут указанный момент времени.

Объявление

template

     typename Duration, typename Predicate>

bool wait_until(

 Lockable& lock,

 std::chrono::time_point const& absolute_time,

 Predicate pred);

Предусловия

Выражение

pred()
должно быть допустимо и возвращать значение, преобразуемое в тип
bool
. Тип
Lockable
удовлетворяет требованиям концепции
Lockable
и
lock
владеет блокировкой.

Результат

Эквивалентно следующему коду:

while (!pred()) {

 if (wait_until(lock, absolute_time) == std::cv_status::timeout)

  return pred();

}

return true;

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

true
, если последнее обращение к
pred()
вернуло
true
;
false
, если функция
Clock::now()
вернула время, большее или равное
absolute_time
, и обращение к
pred()
вернуло
false
.

Примечание. Возможность ложного пробуждения означает, что функция

pred
может вызываться несколько раз (сколько именно, не определено). При любом вызове
pred
мьютекс, на который ссылается объект
lock
, гарантированно будет захвачен, и функция вернет управление тогда и только тогда, когда результатом вычисления
(bool)pred()
является
true
или функция
Clock::now()
вернула время, большее или равное
absolute_time
. Не дается никаких гарантий относительно того, сколько времени будет блокирован вызывающий поток. Гарантируется лишь, что если функция вернула
false
, то значение, возвращенное
Clock::now()
, больше или равно
absolute_time
в точке, где поток разблокировался.

Исключения

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

pred
, или
std::system_error
, если действие не выполнено.

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

Обращения к функциям

notify_one()
,
notify_all()
,
wait()
,
wait_for()
и
wait_until()
одного и того же объекта
std::condition_variable_any
сериализуются. Обращение к
notify_one()
или
notify_all()
будит только потоки, запущенные до этого обращения.

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

В заголовке

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

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

#define ATOMIC_BOOL_LOCK_FREE см. описание

#define ATOMIC_CHAR_LOCK_FREE см. описание

#define ATOMIC_SHORT_LOCK_FREE см. описание

#define ATOMIC_INT_LOCK_FREE см. описание

#define ATOMIC_LONG_LOCK_FREE см. описание

#define ATOMIC_LLONG_LOCK_FREE см. описание

#define ATOMIC_CHAR16_T_LOCK_FREE см. описание

#define ATOMIC_CHAR32_T_LOCK_FREE см. описание

#define ATOMIC_WCHAR_T_LOCK_FREE см. описание

#define ATOMIC_POINTER_LOCK_FREE см. описание


#define ATOMIC_VAR_INIT(value) см. описание


namespace std {

enum memory_order;

struct atomic_flag;

typedef см. описание atomic_bool;

typedef см. описание atomic_char;

typedef см. описание atomic_char16_t;

typedef см. описание atomic_char32_t;

typedef см. описание atomic_schar;

typedef см. описание atomic_uchar;

typedef см. описание atomic_short;

typedef см. описание atomic_ushort;

typedef см. описание atomic_int;

typedef см. описание atomic_uint;

typedef см. описание atomic_long;

typedef см. описание atomic_ulong;

typedef см. описание atomic_llong;

typedef см. описание atomic_ullong;

typedef см. описание atomic_wchar_t;


typedef см. описание atomic_int_least8_t;

typedef см. описание atomic_uint_least8_t;

typedef см. описание atomic_int_least16_t;

typedef см. описание atomic_uint_least16_t;

typedef см. описание atomic_int_least32_t;

typedef см. описание atomic_uint_least32_t;

typedef см. описание atomic_int_least64_t;

typedef см. описание atomic_uint_least64_t;

typedef см. описание atomic_int_fast8_t;

typedef см. описание atomic_uint_fast8_t;

typedef см. описание atomic_int_fast16_t;

typedef см. описание atomic_uint_fast16_t;

typedef см. описание atomic_int_fast32_t;

typedef см. описание atomic_uint_fast32_t;

typedef см. описание atomic_int_fast64_t;

typedef см. описание atomic_uint_fast64_t;

typedef см. описание atomic_int8_t;

typedef см. описание atomic_uint8_t;

typedef см. описание atomic_int16_t;

typedef см. описание atomic_uint16_t;

typedef см. описание atomic_int32_t;

typedef см. описание atomic_uint32_t;

typedef см. описание atomic_int64_t;

typedef см. описание atomic_uint64_t;

typedef см. описание atomic_intptr_t;

typedef см. описание atomic_uintptr_t;

typedef см. описание atomic_size_t;

typedef см. описание atomic_ssize_t;

typedef см. описание atomic_ptrdiff_t;

typedef см. описание atomic_intmax_t;

typedef см. описание atomic_uintmax_t;


template

struct atomic;


extern "C" void atomic_thread_fence(memory_order order);

extern "C" void atomic_signal_fence(memory_order order);


template

T kill_dependency(T);

}

D.3.1.
std::atomic_xxx
, псевдонимы типов

Для совместимости с ожидаемым стандартом С предоставляются псевдонимы

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


Таблица D.1. Псевдонимы атомарных типов и соответствующие им специализации

std::atomic<>

std::atomic_itype
Специализация
std::atomic<>
std::atomic_char
std::atomic
std::atomic_schar
std::atomic
std::atomic_uchar
std::atomic
std::atomic_short
std::atomic
std::atomic_ushort
std::atomic
std::atomic_int
std::atomic
std::atomic_uint
std::atomic
std::atomic_long
std::atomic
std::atomic_ulong
std::atomic
std::atomic_llong
std::atomic
std::atomic_ullong
std::atomic
std::atomic_wchar_t
std::atomic
std::atomic_char16_t
std::atomic
std::atomic_char32_t
std::atomic

D.3.2.
ATOMIC_xxx_LOCK_FREE
, макросы

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

Объявления макросов

#define ATOMIC_BOOL_LOCK_FREE см. описание

#define ATOMIC_CHAR_LOCK_FREE см. описание

#define ATOMIC_SHORT_LOCK_FREE см. описание

#define ATOMIC_INT_LOCK_FREE см. описание

#define ATOMIC_LONG_LOCK_FREE см. описание

#define ATOMIC_LLONG_LOCK_FREE см. описание

#define ATOMIC_CHAR16_T_LOCK_FREE см. описание

#define ATOMIC_CHAR32_T_LOCK_FREE см. описание

#define ATOMIC_WCHAR_T_LOCK_FREE см. описание

#define ATOMIC_POINTER_LOCK_FREE см. описание

Значением

ATOMIC_xxx_LOCK_FREE
может быть 0, 1 или 2. Значение 0 означает, что операции над знаковыми и беззнаковыми атомарными типами, соответствующими типу
xxx
, никогда не свободны от блокировок; 1 — что операции могут быть свободны от блокировок для одних экземпляров этих типов и не свободны для других; 2 — что операции всегда свободны от блокировок. Например, если ATOMIC
_INT_LOCK_FREE
равно 2, то операции над любыми экземплярами
std::atomic
и
std::atomic
свободны от блокировок.

Макрос

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

D.3.3.
ATOMIC_VAR_INIT
, макрос

Макрос

ATOMIC_VAR_INIT
позволяет инициализировать атомарную переменную конкретным значением.

Объявление

#define ATOMIC_VAR_INIT(value) см. описание

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

std::atomic x = ATOMIC_VAR_INIT(val);

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

std::atomic i = ATOMIC_VAR_INIT(42);

std::string s;

std::atomic p = ATOMIC_VAR_INIT(&s);

Такая инициализация не атомарна, то есть любой доступ из другого потока к инициализируемой переменной в случае, когда инициализация не происходит-раньше этого доступа, приводит к гонке за данными и, следовательно, к неопределённому поведению.

D.3.4.
std::memory_order
, перечисление

Перечисление

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

Объявление

typedef enum memory_order {

 memory_order_relaxed, memory_order_consume,

 memory_order_acquire, memory_order_release,

 memory_order_acq_rel, memory_order_seq_cst

} memory_order;

Операции, помеченные элементами этого перечисления, ведут себя, как описано ниже (подробное описание упорядочения доступа к памяти см. в главе 5).


              STD::MEMORY_ORDER_RELAXED
            

Операция не обеспечивает никаких дополнительных ограничений на упорядочение.


              STD::MEMORY_ORDER_RELEASE
            

Операция освобождения указанной ячейки памяти. Следовательно, она синхронизируется-с операцией захвата той же ячейки памяти, которая читает сохраненное значение.


              STD::MEMORY_ORDER_ACQUIRE
            

Операция захвата указанной ячейки памяти. Если сохраненное значение было записано операцией освобождения, то сохранение синхронизируется-с этой операцией.


              STD::MEMORY_ORDER_ACQ_REL
            

Операция чтения-модификации-записи. Ведет себя так, как будто одновременно заданы ограничения

std::memory_order_acquire
и
std::memory_order_release
для доступа к указанной ячейке памяти.


              STD::MEMORY_ORDER_SEQ_CST
            

Операция является частью цепочки последовательно согласованных операций, на которой определено полное упорядочение. Кроме того, если это сохранение, то оно ведет себя как операция с ограничением

std::memory_order_release
, если загрузка — то как операция с ограничением
std::memory_order_acquire
, а если это операция чтения-модификации-записи, то она ведет себя как операция с обоими ограничениями
std::memory_order_acquire
и
std::memory_order_release
. Эта семантика по умолчанию подразумевается для всех операций.


              STD::MEMORY_ORDER_CONSUME
            

Операция потребления указанной ячейки памяти.

D.3.5.
std::atomic_thread_fence
, функция

Функция

std::atomic_thread_fence()
вставляет в программу «барьер», чтобы принудительно обеспечить упорядочение доступа к памяти со стороны нескольких операций.

Объявление

extern "С" void atomic_thread_fence(std::memory_order order);

Результат

Вставляет барьер с требуемыми ограничениями на упорядочение доступа к памяти.

Барьер, для которого параметр

order
равен
std::memory_order_release
,
std::memory_order_acq_rel
или
std::memory_order_seq_cst
синхронизируется-с операцией захвата некоторой ячейки памяти, если эта операция читает значение, сохраненное атомарной операцией, следующей за барьером в том же потоке, где поставлен барьер.

Операция освобождения синхронизируется-с барьером, для которого параметр

order
равен
std::memory_order_acquire
,
std::memory_order_acq_rel
или
std::memory_order_seq_cst
, если эта операция освобождения сохраняет значение, которое читается атомарной операцией, предшествующей барьеру, в том же потоке, где поставлен барьер.

Исключения

Нет.

D.3.6.
std::atomic_signal_fence
, функция

Функция

std::atomic_signal_fence()
вставляет в программу «барьер», чтобы принудительно обеспечить упорядочение доступа к памяти со стороны операций в некотором потоке и операций в обработчике сигнала, находящемся в том же потоке.

Объявление

extern "С" void atomic_signal_fence(std::memory_order order);

Результат

Вставляет барьер с требуемыми ограничениями на упорядочение доступа к памяти. Функция эквивалентна

std::atomic_thread_fence(order)
с тем отличием, что ограничения применяются только к потоку и обработчику сигнала в том же потоке.

Исключения

Нет.

D.3.7.
std::atomic_flag
, класс

Класс

std::atomic_flag
предоставляет самый простой атомарный флаг. Это единственный тип данных в стандарте С++, который гарантированно свободен от блокировок (хотя в большинстве реализаций этим свойством обладают и многие другие атомарные типы).

Объект типа

std::atomic_flag
может находиться в одном из двух состояний: установлен или сброшен.

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

struct atomic_flag {

 atomic_flag() noexcept = default;

 atomic_flag(const atomic_flag&) = delete;

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

 atomic_flag& operator=(const atomic_flag&) volatile = delete;

 bool test_and_set(memory_order = memory_order_seq_cst)

  volatile noexcept;

 bool test_and_set(memory_order = memory_order_seq_cst) noexcept;

 void clear(memory_order = memory_order_seq_cst)

  volatile noexcept;

 void clear(memory_order = memory_order_seq_cst) noexcept;

};

bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept;

bool atomic_flag_test_and_set(atomic_flag*) noexcept;

bool atomic_flag_test_and_set_explicit(

 volatile atomic_flag*, memory_order) noexcept;

bool atomic_flag_test_and_set_explicit(

 atomic_flag*, memory_order) noexcept;

void atomic_flag_clear(volatile atomic_flag*) noexcept;

void atomic_flag_clear(atomic_flag*) noexcept;

void atomic_flag_clear_explicit(

 volatile atomic_flag*, memory_order) noexcept;

void atomic_flag_clear_explicit(

 atomic_flag*, memory_order) noexcept;


#define ATOMIC_FLAG_INIT unspecified


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

He оговаривается, в каком состоянии находится сконструированный по умолчанию экземпляр

std::atomic_flag
: установлен или сброшен. Для объектов со статическим временем жизни обеспечивается статическая инициализация.

Объявление

std::atomic_flag() noexcept = default;

Результат

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

std::atomic_flag
в неопределенном состоянии.

Исключения

Нет.


              STD::ATOMIC_FLAG
            
, ИНИЦИАЛИЗАЦИЯ МАКРОСОМ

              ATOMIC_FLAG_INIT
            

Экземпляр типа

std::atomic_flag
может быть инициализирован макросом
ATOMIC_FLAG_INIT
, и в таком случае его начальное состояние — сброшен. Для объектов со статическим временем жизни обеспечивается статическая инициализация.

Объявление

#define ATOMIC_FLAG_INIT unspecified

Использование

std::atomic_flag flag = ATOMIC_FLAG_INIT;

Результат

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

std::atomic_flag
в состоянии сброшен.

Исключения

Нет.


              STD::ATOMIC_FLAG::TEST_AND_SET
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно устанавливает флаг и проверяет, был ли он установлен.

Объявление

bool test_and_set(memory_order order = memory_order_seq_cst)

 volatile noexcept;

bool test_and_set(memory_order order = memory_order_seq_cst)

 noexcept;

Результат

Атомарно устанавливает флаг.

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

true
, если флаг был установлен в точке вызова;
false
, если флаг был сброшен.

Исключения

Нет.

Примечание. Это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей

*this
.


              STD::ATOMIC_FLAG_TEST_AND_SET
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно устанавливает флаг и проверяет, был ли он установлен.

Объявление

bool atomic_flag_test_and_set(

 volatile atomic_flag* flag) noexcept;

bool atomic_flag_test_and_set(atomic_flag* flag) noexcept;

Результат

return flag->test_and_set();


              STD::ATOMIC_FLAG_TEST_AND_SET_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно устанавливает флаг и проверяет, был ли он установлен.

Объявление

bool atomic_flag_test_and_set_explicit(

 volatile atomic_flag* flag, memory_order order) noexcept;

bool atomic_flag_test_and_set_explicit(

 atomic_flag* flag, memory_order order) noexcept;

Результат

return flag->test_and_set(order);

STD::ATOMIC_FLAG::CLEAR
, ФУНКЦИЯ-ЧЛЕН

Атомарно сбрасывает флаг.

Объявление

void clear(memory_order order = memory_order_seq_cst) volatile noexcept;

void clear(memory_order order = memory_order_seq_cst) noexcept;

Предусловия

Параметр order должен принимать одно из значений

std::memory_order_relaxed
,
std::memory_order_release
или
std::memory_order_seq_cst
.

Результат

Атомарно сбрасывает флаг.

Исключения

Нет.

Примечание. Это атомарная операция сохранения для ячейки памяти, содержащей

*this
.


              STD::ATOMIC_FLAG_CLEAR
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно сбрасывает флаг.

Объявление

void atomic_flag_clear(volatile atomic_flag* flag) noexcept;

void atomic_flag_clear(atomic_flag* flag) noexcept;

Результат

flag->clear();


              STD::ATOMIC_FLAG_CLEAR_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно сбрасывает флаг.

Объявление

void atomic_flag_clear_explicit(

 volatile atomic_flag* flag, memory_order order) noexcept;

void atomic_flag_clear_explicit(

 atomic_flag* flag, memory_order order) noexcept;

Результат

return flag->clear(order);

D.3.8. Шаблон класса
std::atomic

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

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

Параметр шаблона

BaseТуре
должен:

• иметь тривиальный конструктор по умолчанию;

• иметь тривиальный копирующий оператор присваивания;

• иметь тривиальный деструктор;

• допускать побитовое сравнение на равенство.

По существу, это означает, что конкретизация

std::atomic<некоторый-встроенный-тип>
допустима, как и конкретизация
std::atomic<некоторая-простая-структура>
, но такие вещи, как
std::atomic
, недопустимы.

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

x++
.

Экземпляры

std::atomic
не удовлетворяют требованиям концепций
CopyConstructible
и
CopyAssignable
, потому что такие операции невозможно выполнить атомарно.

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

template

struct atomic {

 atomic() noexcept = default;

 constexpr atomic(BaseType) noexcept;

 BaseType operator=(BaseType) volatile noexcept;

 BaseType operator=(BaseType) noexcept;


 atomic(const atomic&) = delete;

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

 atomic& operator=(const atomic&) volatile = delete;


 bool is_lock_free() const volatile noexcept;

 bool is_lock_free() const noexcept;

 void store(BaseType, memory_order = memory_order_seq_cst)

  volatile noexcept;

 void store(BaseType, memory_order = memory_order_seq_cst)

  noexcept;

 BaseType load(memory_order = memory_order_seq_cst)

  const volatile noexcept;

 BaseType load(memory_order = memory_order_seq_cst)

  const noexcept;

 BaseType exchange(BaseType, memory_order = memory_order_seq_cst)

  volatile noexcept;

 BaseType exchange(BaseType, memory_order = memory_order_seq_cst)

  noexcept;


 bool compare_exchange_strong(

  BaseType & old_value, BaseType new_value,

  memory_order order = memory_order_seq_cst) volatile noexcept;

 bool compare_exchange_strong(

  BaseType & old_value, BaseType new_value,

  memory_order order = memory_order_seq_cst) noexcept;

 bool compare_exchange_strong(

  BaseType & old_value, BaseType new_value,

  memory_order success_order,

  memory_order failure_order) volatile noexcept;

 bool compare_exchange_strong(

  BaseType & old_value, BaseType new_value,

  memory_order success_order,

  memory_order failure_order) noexcept;

 bool compare_exchange_weak(

  BaseType & old_value, BaseType new_value,

  memory_order order = memory_order_seq_cst)

  volatile noexcept;

 bool compare_exchange_weak(

  BaseType & old_value, BaseType new_value,

  memory_order order = memory_order_seq_cst) noexcept;

 bool compare_exchange_weak(

  BaseType & old_value, BaseType new_value,

  memory_order success_order,

  memory_order failure_order) volatile noexcept;

 bool compare_exchange_weak(

  BaseType & old_value, BaseType new_value,

  memory_order success_order,

  memory_order failure_order) noexcept;


 operator BaseType() const volatile noexcept;

 operator BaseType() const noexcept;

};


template

bool atomic_is_lock_free(

 volatile const atomic*) noexcept;


template

 bool atomic_is_lock_free(const atomic*)

 noexcept;


template

void atomic_init(volatile atomic*, void*) noexcept;


template

void atomic_init(atomic*, void*) noexcept;


template

BaseType atomic_exchange(

 volatile atomic*, memory_order) noexcept;


template

BaseType atomic_exchange(

 atomic*, memory_order) noexcept;


template

BaseType atomic_exchange_explicit(

 volatile atomic*, memory_order) noexcept;


template

BaseType atomic_exchange_explicit(

 atomic*, memory_order) noexcept;


template

void atomic_store(volatile atomic*, BaseType) noexcept;


template

void atomic_store(atomic*, BaseType) noexcept;


template

void atomic_store_explicit(

 volatile atomic*, BaseType, memory_order) noexcept;


template

void atomic_store_explicit(

 atomic*, BaseType, memory_order) noexcept;


template

BaseType atomic_load(volatile const atomic*) noexcept;


template

BaseType atomic_load(const atomic*) noexcept;


template

BaseType atomic_load_explicit(

 volatile const atomic*, memory_order) noexcept;


template

BaseType atomic_load_explicit(

 const atomic*, memory_order) noexcept;


template

bool atomic_compare_exchange_strong(

 volatile atomic*,

 BaseType * old_value, BaseType new_value) noexcept;


template

bool atomic_compare_exchange_strong(

 atomic*,

 BaseType * old_value, BaseType new_value) noexcept;


template

bool atomic_compare_exchange_strong_explicit(

 volatile atomic*, BaseType * old_value,

 BaseType new_value, memory_order success_order,

 memory_order failure_order) noexcept;


template

bool atomic_compare_exchange_strong_explicit(

 atomic*,

 BaseType * old_value, BaseType new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;


template

bool atomic_compare_exchange_weak(

 volatile atomic*,

 BaseType * old_value, BaseType new_value) noexcept;


template

bool atomic_compare_exchange_weak(

 atomic*,

 BaseType * old_value, BaseType new_value) noexcept;


template

bool atomic_compare_exchange_weak_explicit(

 volatile atomic*,

 BaseType * old_value, BaseType new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;


template

bool atomic_compare_exchange_weak_explicit(

 atomic*,

 BaseType * old_value, BaseType new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

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


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

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

std::atomic
со значением, инициализированным по умолчанию.

Объявление

atomic() noexcept;

Результат

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

std::atomic
со значением, инициализированным по умолчанию. Для объектов со статическим временем жизни обеспечивается статическая инициализация.

Примечание. Если время жизни объекта

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

Исключения

Нет.


              STD::ATOMIC_INIT
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Неатомарно сохраняет указанное значение в объекте типа

std::atomic
.

Объявление

template

void atomic_init(

 atomic volatile* p, BaseType v) noexcept;


template

void atomic_init(atomic* p, BaseType v) noexcept;

Результат

Неатомарно сохраняет значение

v
в
*p
. Вызов
atomic_init()
с передачей в качестве аргумента объекта
atomic
, который не был сконструирован по умолчанию или над которым производились какие-нибудь операции после конструирования, является неопределенным поведением.

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

p
, из другого потока (даже с помощью атомарной операции) представляет собой гонку за данными.

Исключения

Нет.


              STD::ATOMIC
            
, КОНВЕРТИРУЮЩИЙ КОНСТРУКТОР

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

std::atomic
из переданного значения типа
BaseType
.

Объявление

constexpr atomic(BaseType b) noexcept;

Результат

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

std::atomic
из значения
b
. Для объектов со статическим временем жизни обеспечивается статическая инициализация.

Исключения

Нет.


              STD::ATOMIC
            
, КОНВЕРТИРУЮЩИЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Сохраняет новое значение в

*this
.

Объявление

BaseType operator=(BaseType b) volatile noexcept;

BaseType operator=(BaseType b) noexcept;

Результат

return this->store(b);


              STD::ATOMIC::IS_LOCK_FREE
            
, ФУНКЦИЯ-ЧЛЕН

Сообщает, являются ли операции над

*this
свободными от блокировок.

Объявление

bool is_lock_free() const volatile noexcept;

bool is_lock_free() const noexcept;

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

true
, если операции над
*this
свободны от блокировок, иначе
false
.

Исключения

Нет.


              STD::ATOMIC_IS_LOCK_FREE
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Сообщает, являются ли операции над

*this
свободными от блокировок.

Объявление

template

bool atomic_is_lock_free(

 volatile const atomic* p) noexcept;

template

bool atomic_is_lock_free(const atomic* p) noexcept;

Результат

return p->is_lock_free();


              STD::ATOMIC::LOAD
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно загружает текущее значение объекта

std::atomic
.

Объявление

BaseType load(memory_order order = memory_order_seq_cst)

 const volatile noexcept;

BaseType load(

 memory_order order = memory_order_seq_cst) const noexcept;

Предусловия

Параметр

order
должен принимать одно из значений
std::memory_order_relaxed
,
std::memory_order_acquire
,
std: :memory_order_consume
или
std::memory_order_seq_cst
.

Результат

Атомарно загружает текущее, хранящееся в

*this
.

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

Значение, хранящееся в

*this
, в точке вызова.

Исключения

Нет.

Примечание. Это атомарная операция загрузки для ячейки памяти, содержащей

*this
.


              STD::ATOMIC_LOAD
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно загружает текущее значение объекта

std::atomic
.

Объявление

template

BaseType atomic_load(volatile const atomic* p) noexcept;

template

BaseType atomic_load(const atomic* p) noexcept;

Результат

return p->load();


              STD::ATOMIC_LOAD_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно загружает текущее значение объекта

std::atomic
.

Объявление

template

BaseType atomic_load_explicit(

 volatile const atomic* p,

 memory_order order) noexcept;

template

BaseType atomic_load_explicit(

 const atomic* p, memory_order order) noexcept;

Результат

return p->load(order);


              STD::ATOMIC::OPERATOR
            
, ОПЕРАТОР ПРЕОБРАЗОВАНИЯ В ТИП BASETYPE

Загружает значение, хранящееся в

*this
.

Объявление

operator BaseType() const volatile noexcept;

operator BaseType() const noexcept;

Результат

return this->load();


              STD::ATOMIC::STORE
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно сохраняет новое значение в объекте

atomic
.

Объявление

void store(

 BaseType new_value, memory_order order = memory_order_seq_cst)

 volatile noexcept;

void store(

 BaseType new_value, memory_order order = memory_order_seq_cst)

 noexcept;

Предусловия

Параметр

order
должен принимать одно из значений
std::memory_order_relaxed
,
std::memory_order_release
или
std::memory_order_seq_cst
.

Результат

Атомарно сохраняет значение

new_value
в
*this
.

Исключения

Нет.

Примечание. Это атомарная операция сохранения для ячейки памяти, содержащей

*this
.


              STD::ATOMIC_STORE
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно сохраняет новое значение в объекте

atomic
.

Объявление

template

void atomic_store(

 volatile atomic* p, BaseType new_value) noexcept;

template

void atomic_store(

 atomic* p, BaseType new_value) noexcept;

Результат

p->store(new_value);


              STD::ATOMIC_STORE_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно сохраняет новое значение в объекте

atomic
.

Объявление

template

void atomic_store_explicit(

 volatile atomic* p, BaseType new_value,

 memory_order order) noexcept;

template

void atomic_store_explicit(

 atomic* p, BaseType new_value,

 memory_order order) noexcept;

Результат

p->store(new_value, order);


              STD::ATOMIC::EXCHANGE
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно сохраняет новое значение и читает старое.

Объявление

BaseType exchange(

BaseType new_value,

 memory_order order = memory_order_seq_cst) volatile noexcept;

Результат

Атомарно сохраняет значение

new_value
в
*this
и извлекает прежнее значение
*this
.

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

Значение

*this
непосредственно перед сохранением.

Исключения

Нет.

Примечание. Это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей

*this
.


              STD::ATOMIC_EXCHANGE
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно сохраняет новое значение в объекте

atomic
и читает предыдущее значение.

Объявление

template

BaseType atomic_exchange(

 volatile atomic* p, BaseType new_value) noexcept;

template

BaseType atomic_exchange(

 atomic* p, BaseType new_value) noexcept;

Результат

return p->exchange(new_value);


              STD::ATOMIC_EXCHANGE_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно сохраняет новое значение в объекте

atomic
и читает предыдущее значение.

Объявление

template

BaseType atomic_exchange_explicit(

 volatile atomic* p,

 BaseType new_value, memory_order order)

 noexcept;

template

BaseType atomic_exchange_explicit(

 atomic* p,

 BaseType new_value, memory_order order) noexcept;

Результат

return p->exchange(new_value, order);


              STD::ATOMIC::COMPARE_EXCHANGE_STRONG
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно сравнивает значение с ожидаемым и, если они равны, сохраняет новое значение. Если значения не равны, то заменяет ожидаемое значение прочитанным.

Объявление

bool compare_exchange_strong(

 BaseType& expected, BaseType new_value,

 memory_order order = std::memory_order_seq_cst)

 volatile noexcept;

bool compare_exchange_strong(

 BaseType& expected, BaseType new_value,

 memory_order order = std::memory_order_seq_cst) noexcept;

bool compare_exchange_strong(

 BaseType& expected, BaseType new_value,

 memory_order success_order, memory_order failure_order)

 volatile noexcept;

bool compare_exchange_strong(

 BaseType& expected, BaseType new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

Предусловия

Параметр

failure_order
не должен быть равен
std::memory_order_release
или
std::memory_order_acq_rel
.

Результат

Атомарно сравнивает

expected
со значением, хранящимся в
*this
, применяя побитовое сравнение, и сохраняет
new_value
в
*this
, если значения равны. В противном случае записывает в
expected
прочитанное значение.

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

true
, если значение, хранящееся в
*this
, совпало с
expected
. В противном случае
false
.

Исключения

Нет.

Примечание. Этот перегруженный вариант функции с тремя параметрами эквивалентен перегруженному варианту с четырьмя параметрами, где

success_order == order
и
failure_order == order
, с тем отличием, что если
order
равно
std::memory_order_acq_rel
, то
failure_order
равно
std::memory_order_acquire
, а если
order
равно
std::memory_order_release
, то
failure_order
равно
std::memory_order_relaxed
.

Примечание. Если результат равен

true
, то это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей
*this
, с упорядочением доступа к памяти
success_order
; в противном случае это атомарная операция загрузки для ячейки памяти, содержащей
*this
, с упорядочением доступа к памяти
failure_order
.


              STD::ATOMIC_COMPARE_EXCHANGE_STRONG
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно сравнивает значение с ожидаемым и, если они равны, сохраняет новое значение. Если значения не равны, то заменяет ожидаемое значение прочитанным.

Объявление

template

bool atomic_compare_exchange_strong(

 volatile atomic* p,

 BaseType * old_value, BaseType new_value) noexcept;

template

bool atomic_compare_exchange_strong(

 atomic* p,

 BaseType * old_value, BaseType new_value) noexcept;

Результат

return p->compare_exchange_strong(*old_value, new_value);


              STD::ATOMIC_COMPARE_EXCHANGE_STRONG_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно сравнивает значение с ожидаемым и, если они равны, сохраняет новое значение. Если значения не равны, то заменяет ожидаемое значение прочитанным.

Объявление

template

bool atomic_compare_exchange_strong_explicit(

 volatile atomic* p,

 BaseType * old_value, BaseType new_value,

 memory_order success_order, memory_order failure_order)

 noexcept;

template

bool atomic_compare_exchange_strong_explicit(

 atomic* p,

 BaseType * old_value, BaseType new_value,

 memory_order success_order, memory_order failure_order)

 noexcept;

Результат

return p->compare_exchange_strong(

*old_value, new_value, success_order, failure_order) noexcept;


              STD::ATOMIC::COMPARE_EXCHANGE_WEAK
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно сравнивает значение с ожидаемым и, если они равны и обновление может быть произведено атомарно, то сохраняет новое значение. Если значения не равны или обновление не может быть произведено атомарно, то заменяет ожидаемое значение прочитанным.

Объявление

bool compare_exchange_weak(

 BaseType& expected, BaseType new_value,

 memory_order order = std::memory_order_seq_cst)

 volatile noexcept;

bool compare_exchange_weak(

 BaseType& expected, BaseType new_value,

 memory_order order = std::memory_order_seq_cst) noexcept;

bool compare_exchange_weak(

 BaseType& expected, BaseType new_value,

 memory_order success_order, memory_order failure_order)

 volatile noexcept;

bool compare_exchange_weak(

 BaseType& expected, BaseType new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

Предусловия

Параметр

failure_order
не должен быть равен
std::memory_order_release
или
std::memory_order_acq_rel
.

Результат

Атомарно сравнивает

expected
со значением, хранящимся в
*this
, применяя побитовое сравнение, и сохраняет
new_value
в
*this
, если значения равны. Если значения не равны или обновление не может быть произведено атомарно, записывает в
expected
прочитанное значение.

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

true
, если значение, хранящееся в
*this
, совпало с
expected
и
new_value
успешно сохранено в
*this
. В противном случае
false
.

Исключения

Нет.

Примечание. Этот перегруженный вариант функции с тремя параметрами эквивалентен перегруженному варианту с четырьмя параметрами, где

success_order == order
и
failure_order == order
, с тем отличием, что если
order
равно
std::memory_order_acq_rel
, то
failure_order
равно
std::memory_order_acquire
, а если order равно
std::memory_order_release
, то
failure_order
равно
std::memory_order_relaxed
.

Примечание. Если результат равен

true
, то это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей
*this
, с упорядочением доступа к памяти
success_order
; в противном случае это атомарная операция загрузки для ячейки памяти, содержащей
*this
, с упорядочением доступа к памяти
failure_order
.


              STD::ATOMIC_COMPARE_EXCHANGE_WEAK
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно сравнивает значение с ожидаемым и, если они равны и обновление может быть произведено атомарно, то сохраняет новое значение. Если значения не равны или обновление не может быть произведено атомарно, то заменяет ожидаемое значение прочитанным.

Объявление

template

bool atomic_compare_exchange_weak(

 volatile atomic* p,

 BaseType * old_value, BaseType new_value) noexcept;

template

bool atomic_compare_exchange_weak(

 atomic* p,

 BaseType * old_value, BaseType new_value) noexcept;

Результат

return p->compare_exchange_weak(*old_value, new_value);


              STD::ATOMIC_COMPARE_EXCHANGE_WEAK_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно сравнивает значение с ожидаемым и, если они равны и обновление может быть произведено атомарно, то сохраняет новое значение. Если значения не равны или обновление не может быть произведено атомарно, то заменяет ожидаемое значение прочитанным.

template

bool atomic_compare_exchange_weak_explicit(

 volatile atomic* p,

 BaseType * old_value, BaseType new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

template

bool atomic_compare_exchange_weak_explicit(

 atomic* p,

 BaseType * old_value, BaseType new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

Результат

return p->compare_exchange_weak(

 *old_value, new_value, success_order, failure_order);

D.3.9. Специализации шаблона
std::atomic

Предоставляются специализации шаблона

std::atomic
для целочисленных и указательных типов. Для целочисленных типов специализации обеспечивают атомарные операции сложения, вычитания и поразрядные в дополнение к имеющимся в основном шаблоне. Для указательных типов в дополнение к основному шаблону предоставляются арифметические операции над указателями.

Имеются специализации для следующих целочисленных типов:

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

а также для типа

std::atomic
при любом типе
T
.

D.3.10. Специализации
std::atomic<integral-type>

Специализации

std::atomic<integral-type>
шаблона класса
std::atomic
дают атомарный целочисленный тип для каждого фундаментального целочисленного типа, с полным набором операций.

Ниже перечислены все такие специализации шаблона

std::atomic<>
:

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

std::atomic

Экземпляры этих специализаций не удовлетворяют требованиям концепций

CopyConstructible
и
CopyAssignable
, поскольку такие операции невозможно выполнить атомарно.

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

template<>

struct atomic<integral-type> {

 atomic() noexcept = default;

 constexpr atomic(integral-type) noexcept;

 bool operator=(integral-type) volatile noexcept;


 atomic(const atomic&) = delete;

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

 atomic& operator=(const atomic&) volatile = delete;


 bool is_lock_free() const volatile noexcept;

 bool is_lock_free() const noexcept;


 void store(

  integral-type, memory_order = memory_order_seq_cst)

  volatile noexcept;

 void store(

  integral-type, memory_order = memory_order_seq_cst) noexcept;

 integral-type load(memory_order = memory_order_seq_cst)

  const volatile noexcept;

 integral-type load(

  memory_order = memory_order_seq_cst) const noexcept;

 integral-type exchange(

  integral-type,

  memory_order = memory_order_seq_cst) volatile noexcept;

 integral-type exchange(

  integral-type, memory_order = memory_order_seq_cst) noexcept;


 bool compare_exchange_strong(

  integral-type & old_value, integral-type new_value,

  memory_order order = memory_order_seq_cst)

  volatile noexcept;

 bool compare_exchange_strong(

  integral-type & old_value, integral-type new_value,

  memory_order order = memory_order_seq_cst) noexcept;

 bool compare_exchange_strong(

  integral-type & old_value, integral-type new_value,

  memory_order success_order, memory_order failure_order)

  volatile noexcept;

 bool compare_exchange_strong(

  integral-type & old_value, integral-type new_value,

  memory_order success_order,

  memory_order failure_order) noexcept;

 bool compare_exchange_weak(

  integral-type & old_value, integral-type new_value,

  memory_order order = memory_order_seq_cst) volatile noexcept;

 bool compare_exchange_weak(

  integral-type & old_value, integral-type new_value,

  memory_order order = memory_order_seq_cst) noexcept;

 bool compare_exchange_weak(

  integral-type & old_value, integral-type new_value,

  memory_order success_order, memory_order failure_order)

  volatile noexcept;

 bool compare_exchange_weak(

  integral-type & old_value, integral-type new_value,

  memory_order success_order,

  memory_order failure_order) noexcept;


 operator integral-type() const volatile noexcept;

 operator integral-type() const noexcept;

 integral-type fetch_add(

  integral-type, memory_order = memory_order_seq_cst)

  volatile noexcept;

 integral-type fetch_add(

  integral-type, memory_order = memory_order_seq_cst) noexcept;

 integral-type fetch_sub(

  integral-type, memory_order = memory_order_seq_cst)

  volatile noexcept;

 integral-type fetch_sub(

  integral-type, memory_order = memory_order_seq_cst) noexcept;

 integral-type fetch_and(

  integral-type, memory_order = memory_order_seq_cst)

  volatile noexcept;

 integral-type fetch_and(

  integral-type, memory_order = memory_order_seq_cst) noexcept;

 integral-type fetch_or(

  integral-type, memory_order = memory_order_seq_cst)

  volatile noexcept;

 integral-type fetch_or(

  integral-type, memory_order = memory_order_seq_cst) noexcept;

 integral-type fetch_xor(

  integral-type, memory_order = memory_order_seq_cst)

  volatile noexcept;

 integral-type fetch_xor(

  integral-type, memory_order = memory_order_seq_cst) noexcept;

 integral-type operator++() volatile noexcept;

 integral-type operator++() noexcept;

 integral-type operator++(int) volatile noexcept;

 integral-type operator++(int) noexcept;

 integral-type operator--() volatile noexcept;

 integral-type operator--() noexcept;

 integral-type operator--(int) volatile noexcept;

 integral-type operator--(int) noexcept;


 integral-type operator+=(integral-type) volatile noexcept;

 integral-type operator+=(integral-type) noexcept;

 integral-type operator-=(integral-type) volatile noexcept;

 integral-type operator-=(integral-type) noexcept;

 integral-type operator&=(integral-type) volatile noexcept;

 integral-type operator&=(integral-type) noexcept;

 integral-type operator|=(integral-type) volatile noexcept;

 integral-type operator|=(integral-type) noexcept;

 integral-type operator^=(integral-type) volatile noexcept;

 integral-type operator^=(integral-type) noexcept;

};


bool atomic_is_lock_free(

 volatile const atomic<integral-type>*) noexcept;

bool atomic_is_lock_free(const atomic<integral-type>*) noexcept;

void atomic_init(

 volatile atomic<integral-type>*, integral-type) noexcept;

void atomic_init(atomic<integral-type>*, integral-type) noexcept;

integral-type atomic_exchange(

 volatile atomic<integral-type>*, integral-type) noexcept;

integral-type atomic_exchange(

 atomic<integral-type>*, integral-type) noexcept;


integral-type atomic_exchange_explicit(

 volatile atomic<integral-type>*, integral-type, memory_order)

 noexcept;

integral-type atomic_exchange_explicit(

 atomic<integral-type>*, integral-type, memory_order) noexcept;

void atomic_store(

 volatile atomic<integral-type>*, integral-type) noexcept;

void atomic_store(

 atomic<integral-type>*, integral-type) noexcept;

void atomic_store_explicit(

 volatile atomic<integral-type>*,

 integral-type, memory_order) noexcept;

void atomic_store_explicit(

 atomic<integral-type>*, integral-type, memory_order) noexcept;

integral-type atomic_load(

 volatile const atomic<integral-type>*) noexcept;

integral-type atomic_load(

 const atomic<integral-type>*) noexcept;

integral-type atomic_load_explicit(

 volatile const atomic<integral-type>*, memory_order) noexcept;

integral-type atomic_load_explicit(

 const atomic<integral-type>*, memory_order) noexcept;

bool atomic_compare_exchange_strong(

 volatile atomic<integral-type>*, integral-type * old_value,

 integral-type new_value) noexcept;

bool atomic_compare_exchange_strong(

 atomic<integral-type>*,

 integral-type * old_value, integral-type new_value) noexcept;

bool atomic_compare_exchange_strong_explicit(

 volatile atomic<integral-type>*,

 integral-type * old_value, integral-type new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

bool atomic_compare_exchange_strong_explicit(

 atomic<integral-type>*,

 integral-type * old_value, integral-type new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

bool atomic_compare_exchange_weak(

 volatile atomic<integral-type>*,

 integral-type * old_value, integral-type new_value) noexcept;

bool atomic_compare_exchange_weak(

 atomic<integral-type>*,

 integral-type * old_value, integral-type new_value) noexcept;

bool atomic_compare_exchange_weak_explicit(

 volatile atomic<integral-type>*,

 integral-type * old_value, integral-type new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

bool atomic_compare_exchange_weak_explicit(

 atomic<integral-type>*,

 integral-type * old_value, integral-type new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

 integral-type atomic_fetch_add(

 volatile atomic<integral-type>*, integral-type) noexcept;

integral-type atomic_fetch_add(

 atomic<integral-type>*, integral-type) noexcept;

integral-type atomic_fetch_add_explicit(

 volatile atomic<integral-type>*, integral-type,

 memory_order) noexcept;

integral-type atomic_fetch_add_explicit(

 atomic<integral-type>*, integral-type, memory_order) noexcept;

integral-type atomic_fetch_sub(

 volatile atomic<integral-type>*, integral-type) noexcept;

integral-type atomic_fetch_sub(

 atomic<integral-type>*, integral-type) noexcept;

integral-type atomic_fetch_sub_explicit(

 volatile atomic<integral-type>*,

 integral-type, memory_order) noexcept;

integral-type atomic_fetch_sub_explicit(

 atomic<integral-type>*, integral-type, memory_order) noexcept;

integral-type atomic_fetch_and(

 volatile atomic<integral-type>*, integral-type) noexcept;

integral-type atomic_fetch_and(

 atomic<integral-type>*, integral-type) noexcept;

integral-type atomic_fetch_and_explicit(

 volatile atomic<integral-type>*,

 integral-type, memory_order) noexcept;

integral-type atomic_fetch_and_explicit(

 atomic<integral-type>*, integral-type, memory_order) noexcept;

integral-type atomic_fetch_or(

 volatile atomic<integral-type>*, integral-type) noexcept;

integral-type atomic_fetch_or(

 atomic<integral-type>*, integral-type) noexcept;

integral-type atomic_fetch_or_explicit(

 volatile atomic<integral-type>*,

 integral-type, memory_order) noexcept;

integral-type atomic_fetch_or_explicit(

 atomic<integral-type>*, integral-type, memory_order) noexcept;

integral-type atomic_fetch_xor(

 volatile atomic<integral-type>*, integral-type) noexcept;

integral-type atomic_fetch_xor(

 atomic<integral-type>*, integral-type) noexcept;

integral-type atomic_fetch_xor_explicit(

 volatile atomic<integral-type>*,

 integral-type, memory_order) noexcept;

integral-type atomic_fetch_xor_explicit(

 atomic<integral-type>*, integral-type, memory_order) noexcept;

Те операции, которые предоставляются также основным шаблоном (см. D.3.8), имеют точно такую же семантику.


              STD::ATOMIC::FETCH_ADD
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно загружает значение и заменяет его суммой его самого и аргумента

i
.

Объявление

fetch_add(

 integral-type i, memory_order order = memory_order_seq_cst)

 volatile noexcept;

integral-type fetch_add(

 integral-type i, memory_order order = memory_order_seq_cst)

 noexcept;

Результат

Атомарно возвращает прежнее значение

*this
и сохраняет в
*this
значение
old-value + i
.

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

Значение

*this
непосредственно перед сохранением.

Исключения

Нет.

Примечание. Это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей

*this
.


              STD::ATOMIC_FETCH_ADD
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно читает значение из экземпляра

atomic<integral-type>
и заменяет его суммой этого значения и аргумента
i
.

Объявление

integral-type atomic_fetch_add(

 volatile atomic<integral-type>* p, integral-type i) noexcept;

integral-type atomic_fetch_add(

 atomic<integral-type>* p, integral-type i) noexcept;

Результат

return p->fetch_add(i);


              STD::ATOMIC_FETCH_ADD_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ

КЛАССА

Атомарно читает значение из экземпляра

atomic<integral-type>
и заменяет его суммой этого значения и аргумента
i
.

Объявление

integral-type atomic_fetch_add_explicit(

 volatile atomic<integral-type>* p, integral-type i,

 memory_order order) noexcept;

integral-type atomic_fetch_add_explicit(

 atomic<integral-type>* p, integral-type i,

 memory_order order) noexcept;

Результат

return p->fetch_add(i,order);


              STD::ATOMIC::FETCH_SUB
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно читает значение и заменяет его разностью этого значения и аргумента

i
.

Объявление

integral-type fetch_sub(

 integral-type i,

 memory_order order = memory_order_seq_cst) volatile noexcept;

integral-type fetch_sub(

 integral-type i,

 memory_order order = memory_order_seq_cst) noexcept;

Результат

Атомарно возвращает прежнее значение

*this
и сохраняет в
*this
значение
old-value - i
.

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

Значение

*this
непосредственно перед сохранением.

Исключения

Нет.

Примечание. Это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей

*this
.


              STD::ATOMIC_FETCH_SUB
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно читает значение из экземпляра

atomic<integral-type>
и заменяет его разностью этого значения и аргумента
i
.

Объявление

integral-type atomic_fetch_sub(

 volatile atomic<integral-type>* p, integral-type i) noexcept;

integral-type atomic_fetch_sub(

 atomic<integral-type>* p, integral-type i) noexcept;

Результат

return p->fetch_sub(i);


              STD::ATOMIC_FETCH_SUB_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно читает значение из экземпляра

atomic<integral-type>
и заменяет его разностью этого значения и аргумента
i
.

Объявление

integral-type atomic_fetch_sub_explicit(

 volatile atomic<integral-type>* p,

 integral-type i, memory_order order) noexcept;

integral-type atomic_fetch_sub_explicit(

 atomic<integral-type>* p,

 integral-type i, memory_order order) noexcept;

Результат

return p->fetch_sub(i, order);


              STD::ATOMIC::FETCH_AND
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно загружает значение и заменяет его результатом операции поразрядное-и между этим значением и аргументом

i
.

Объявление

integral-type fetch_and(

 integral-type i, memory_order order = memory_order_seq_cst)

 volatile noexcept;

integral-type fetch_and(

 integral-type i, memory_order order = memory_order_seq_cst)

 noexcept;

Результат

Атомарно возвращает прежнее значение

*this
и сохраняет в
*this
значение
old-value & i
.

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

Значение

*this
непосредственно перед сохранением.

Исключения

Нет.

Примечание. Это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей

*this
.


              STD::ATOMIC_FETCH_AND
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно читает значение из экземпляра

atomic<integral-type>
и заменяет его результатом операции поразрядное-и между этим значением и аргументом
i
. Объявление

integral-type atomic_fetch_and(

 volatile atomic<integral-type>* p, integral-type i) noexcept;

integral-type atomic_fetch_and(

 atomic<integral-type>* p, integral-type i) noexcept;

Результат

return p->fetch_and(i);


              STD::ATOMIC_FETCH_AND_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно читает значение из экземпляра

atomic<integral-type>
и заменяет его результатом операции поразрядное-и между этим значением и аргументом
i
.

Объявление

integral-type atomic_fetch_and_explicit(

 volatile atomic<integral-type>* p,

 integral-type i, memory_order order) noexcept;

integral-type atomic_fetch_and_explicit(

 atomic<integral-type>* p,

 integral-type i, memory_order order) noexcept;

Результат

return p->fetch_and(i,order);


              STD::ATOMIC::FETCH_OR
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно загружает значение и заменяет его результатом операции поразрядное-или между этим значением и аргументом

i
.

Объявление

integral-type fetch_or(

 integral-type i, memory_order order = memory_order_seq_cst)

volatile noexcept;

integral-type fetch_or(

 integral-type i, memory_order order = memory_order_seq_cst)

 noexcept;

Результат

Атомарно возвращает прежнее значение

*this
и сохраняет в
*this
значение
old-value | i
.

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

Значение

*this
непосредственно перед сохранением.

Исключения

Нет.

Примечание. Это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей

*this
.


              STD::ATOMIC_FETCH_OR
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно читает значение из экземпляра

atomic<integral-type>
и заменяет его результатом операции поразрядное-или между этим значением и аргументом
i
.

Объявление

integral-type atomic_fetch_or(

 volatile atomic<integral-type>* p, integral-type i) noexcept;

integral-type atomic_fetch_or(

 atomic<integral-type>* p, integral-type i) noexcept;

Результат

return p->fetch_or(i);


              STD::ATOMIC_FETCH_OR_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно читает значение из экземпляра

atomic<integral-type>
и заменяет его результатом операции поразрядное-или между этим значением и аргументом i.

Объявление

integral-type atomic_fetch_or_explicit(

 volatile atomic<integral-type>* p,

 integral-type i, memory_order order) noexcept;

integral-type atomic_fetch_or_explicit(

 atomic<integral-type>* p,

 integral-type i, memory_order order) noexcept;

Результат

return p->fetch_or(i, order);


              STD::ATOMIC::FETCH_XOR
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно загружает значение и заменяет его результатом операции поразрядное исключающее-или между этим значением и аргументом i.

Объявление

integral-type fetch_xor(

 integral-type i, memory_order order = memory_order_seq_cst)

 volatile noexcept;

integral-type fetch_xor(

 integral-type i, memory_order order = memory_order_seq_cst)

 noexcept;

Результат

Атомарно возвращает прежнее значение

*this
и сохраняет в
*this
значение
old-value ^ i
.

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

Значение

*this
непосредственно перед сохранением.

Исключения

Нет.

Примечание. Это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей

*this
.


              STD::ATOMIC_FETCH_XOR
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно читает значение из экземпляра

atomic<integral-type>
и заменяет его результатом операции поразрядное исключающее-или между этим значением и аргументом
i
.

Объявление

integral-type atomic_fetch_xor(

 volatile atomic<integral-type>* p, integral-type i) noexcept;

integral-type atomic_fetch_xor(

 atomic<integral-type>* p, integral-type i) noexcept;

Результат

return p->fetch_xor(i);


              STD::ATOMIC_FETCH_XOR_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно читает значение из экземпляра

atomic<integral-type>
и заменяет его результатом операции поразрядное исключающее-или между этим значением и аргументом
i
.

Объявление

integral-type atomic_fetch_xor_explicit(

 volatile atomic<integral-type>* p,

 integral-type i, memory_order order) noexcept;

integral-type atomic_fetch_xor_explicit(

 atomic<integral-type>* p,

 integral-type i, memory_order order) noexcept;

Результат

return p->fetch_xor(i,order);


              STD::ATOMIC::OPERATOR++
            
, ОПЕРАТОР ПРЕДИНКРЕМЕНТА

Атомарно инкрементирует значение, хранящееся в

*this
, и возвращает новое значение.

Объявление

integral-type operator++() volatile noexcept;

integral-type operator++() noexcept;

Результат

return this->fetch_add(1) + 1;


              STD::ATOMIC::OPERATOR++
            
, ОПЕРАТОР ПОСТИНКРЕМЕНТА

Атомарно инкрементирует значение, хранящееся в

*this
, и возвращает старое значение.

Объявление

integral-type operator++(int) volatile noexcept;

integral-type operator++(int) noexcept;

Результат

return this->fetch_add(1);


              STD::ATOMIC::OPERATOR--
            
, ОПЕРАТОР ПРЕДЕКРЕМЕНТА

Атомарно декрементирует значение, хранящееся в

*this
, и возвращает новое значение.

Объявление

integral-type operator--() volatile noexcept;

integral-type operator--() noexcept;

Результат

return this->fetch_sub(1) - 1;


              STD::ATOMIC::OPERATOR--
            
, ОПЕРАТОР ПОСТДЕКРЕМЕНТА

Атомарно декрементирует значение, хранящееся в

*this
, и возвращает старое значение.

Объявление

integral-type operator--(int) volatile noexcept;

integral-type operator--(int) noexcept;

Результат

return this->fetch_sub(1);


              STD::ATOMIC::OPERATOR+=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Атомарно складывает значение аргумента со значением, хранящимся в

*this
, и возвращает новое значение.

Объявление

integral-type operator+=(integral-type i) volatile noexcept;

integral-type operator+=(integral-type i) noexcept;

Результат

return this->fetch_add(i) + i;


              STD::ATOMIC::OPERATOR-=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Атомарно вычитает значение аргумента из значения, хранящегося в

*this
, и возвращает новое значение.

Объявление

integral-type operator-=(integral-type i) volatile noexcept;

integral-type operator-=(integral-type i) noexcept;

Результат

return this->fetch_sub(i, std::memory_order_seq_cst) - i;


              STD::ATOMIC::OPERATOR&=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Атомарно заменяет значение, хранящееся в

*this
, результатом операции поразрядное-и между этим значением и значением аргумента и возвращает новое значение.

Объявление

integral-type operator&=(integral-type i) volatile noexcept;

integral-type operator&=(integral-type i) noexcept;

Результат

return this->fetch_and(i) & i;


              STD::ATOMIC::OPERATOR|=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Атомарно заменяет значение, хранящееся в

*this
, результатом операции поразрядное-или между этим значением и значением аргумента и возвращает новое значение.

Объявление

integral-type operator|=(integral-type i) volatile noexcept;

integral-type operator|=(integral-type i) noexcept;

Результат

return this->fetch_or(i, std::memory_order_seq_cst) | i;


              STD::ATOMIC::OPERATOR^=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Атомарно заменяет значение, хранящееся в

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

Объявление

integral-type operator^=(integral-type i) volatile noexcept;

integral-type operator^=(integral-type i) noexcept;

Результат

return this->fetch_xor(i, std::memory_order_seq_cst) ^ i;


              STD::ATOMIC
            
, ЧАСТИЧНАЯ СПЕЦИАЛИЗАЦИЯ

Частичная специализация

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

Экземпляры

std::atomic
не удовлетворяют требованиям концепций
CopyConstructible
и
CopyAssignable
, поскольку такие операции невозможно выполнить атомарно.

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

template

struct atomic {

 atomic() noexcept = default;

 constexpr atomic(T*) noexcept;

 bool operator=(T*) volatile;

 bool operator=(T*);


 atomic(const atomic&) = delete;

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

 atomic& operator=(const atomic&) volatile = delete;


 bool is_lock_free() const volatile noexcept;

 bool is_lock_free() const noexcept;

 void store(T*, memory_order = memory_order_seq_cst)

  volatile noexcept;

 void store(T*, memory_order = memory_order_seq_cst) noexcept;

 T* load(memory_order = memory_order_seq_cst)

  const volatile noexcept;

 T* load(memory_order = memory_order_seq_cst) const noexcept;

 T* exchange(T*, memory_order = memory_order_seq_cst)

  volatile noexcept;

 T* exchange(T*, memory_order = memory_order_seq_cst) noexcept;


 bool compare_exchange_strong(

  T* & old_value, T* new_value,

  memory_order order = memory_order_seq_cst)

  volatile noexcept;

 bool compare_exchange_strong(

  T* & old_value, T* new_value,

  memory_order order = memory_order_seq_cst) noexcept;

 bool compare_exchange_strong(

  T* & old_value, T* new_value,

  memory_order success_order, memory_order failure_order)

  volatile noexcept;

 bool compare_exchange_strong(

  T* & old_value, T* new_value,

  memory_order success_order,

  memory_order failure_order) noexcept;

 bool compare_exchange_weak(

  T* & old_value, T* new_value,

  memory_order order = memory_order_seq_cst) volatile noexcept;

 bool compare_exchange_weak(

  T* & old_value, T* new_value,

  memory_order order = memory_order_seq_cst) noexcept;

 bool compare_exchange_weak(

  T* & old_value, T* new_value,

  memory_order success_order, memory_order failure_order)

  volatile noexcept;

 bool compare_exchange_weak(

  T* & old_value, T* new_value,

  memory_order success_order,

  memory_order failure_order) noexcept;


 operator T*() const volatile noexcept;

 operator T*() const noexcept;


 T* fetch_add(

  ptrdiff_t, memory_order = memory_order_seq_cst)

  volatile noexcept;

 T* fetch_add(

  ptrdiff_t, memory_order = memory_order_seq_cst) noexcept;

 T* fetch_sub(

  ptrdiff_t, memory_order = memory_order_seq_cst)

  volatile noexcept;

 T* fetch_sub(

  ptrdiff_t, memory_order = memory_order_seq_cst) noexcept;

 T* operator++() volatile noexcept;

 T* operator++() noexcept;

 T* operator++(int) volatile noexcept;

 T* operator++(int) noexcept;

 T* operator--() volatile noexcept;

 T* operator--() noexcept;

 T* operator--(int) volatile noexcept;

 T* operator--(int) noexcept;

 T* operator+=(ptrdiff_t) volatile noexcept;

 T* operator+=(ptrdiff_t) noexcept;

 T* operator-=(ptrdiff_t) volatile noexcept;

 T* operator-=(ptrdiff_t) noexcept;

};


bool atomic_is_lock_free(volatile const atomic*) noexcept;

bool atomic_is_lock_free(const atomic*) noexcept;

void atomic_init(volatile atomic*, T*) noexcept;

void atomic_init(atomic*, T*) noexcept;

T* atomic_exchange(volatile atomic*, T*) noexcept;

T* atomic_exchange(atomic*, T*) noexcept;

T* atomic_exchange_explicit(

 volatile atomic*, T*, memory_order) noexcept;

T* atomic_exchange_explicit(

 atomic*, T*, memory_order) noexcept;

void atomic_store(volatile atomic*, T*) noexcept;

void atomic_store(atomic*, T*) noexcept;

void atomic_store_explicit(

 volatile atomic*, T*, memory_order) noexcept;

void atomic_store_explicit(

 atomic*, T*, memory_order) noexcept;

T* atomic_load(volatile const atomic*) noexcept;

T* atomic_load(const atomic*) noexcept;

T* atomic_load_explicit(

 volatile const atomic*, memory_order) noexcept;

T* atomic_load_explicit(

 const atomic*, memory_order) noexcept;

bool atomic_compare_exchange_strong(

 volatile atomic*, T** old_value, T* new_value) noexcept;

bool atomic_compare_exchange_strong(

 volatile atomic*, T** old_value, T* new_value) noexcept;

bool atomic_compare_exchange_strong_explicit(

 atomic*, T** old_value, T* new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

bool atomic_compare_exchange_strong_explicit(

 atomic*, T** old_value, T* new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

bool atomic_compare_exchange_weak(

 volatile atomic*, T** old_value, T* new_value) noexcept;

bool atomic_compare_exchange_weak(

 atomic*, T** old_value, T* new_value) noexcept;

bool atomic_compare_exchange_weak_explicit(

 volatile atomic*,

 T** old_value, T* new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

bool atomic_compare_exchange_weak_explicit(

 atomic*, T** old_value, T* new_value,

 memory_order success_order,

 memory_order failure_order) noexcept;

T* atomic_fetch_add(volatile atomic*, ptrdiff_t) noexcept;

T* atomic_fetch_add(atomic*, ptrdiff_t) noexcept;

T* atomic_fetch_add_explicit(

 volatile atomic*, ptrdiff_t, memory_order) noexcept;

T* atomic_fetch_add_explicit(

 atomic*, ptrdiff_t, memory_order) noexcept;

T* atomic_fetch_sub(volatile atomic*, ptrdiff_t) noexcept;

T* atomic_fetch_sub(atomic*, ptrdiff_t) noexcept;

T* atomic_fetch_sub_explicit(

 volatile atomic*, ptrdiff_t, memory_order) noexcept;

T* atomic_fetch_sub_explicit(

 atomic*, ptrdiff_t, memory_order) noexcept;

Те операции, которые предоставляются также основным шаблоном (см. приложение D.3.8), имеют точно такую же семантику.


              STD::ATOMIC::FETCH_ADD
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно загружает значение, заменяет его суммой этого значения и аргумента

i
, применяя стандартные правила арифметики указателей, и возвращает старое значение.

Объявление

T* fetch_add(

 ptrdiff_t i, memory_order order = memory_order_seq_cst)

 volatile noexcept;

T* fetch_add(

 ptrdiff_t i, memory_order order = memory_order_seq_cst) noexcept;

Результат

Атомарно возвращает текущее значение

*this
и сохраняет в
*this
значение
old-value + i
.

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

Значение

*this
непосредственно перед сохранением.

Исключения

Нет.

Примечание. Это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей

*this
.


              STD::ATOMIC_FETCH_ADD_EXPLICIT
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно читает значение из экземпляра

atomic
и заменяет его суммой этого значения и аргумента
i
, применяя стандартные правила арифметики указателей.

Объявление

T* atomic_fetch_add_explicit(

 volatile atomic* p, ptrdiff_t i, memory_order order)

 noexcept;

T* atomic_fetch_add_explicit(

 atomic* p, ptrdiff_t i, memory_order order) noexcept;

Результат

return p->fetch_add(i, order);


              STD::ATOMIC::FETCH_SUB
            
, ФУНКЦИЯ-ЧЛЕН

Атомарно загружает значение, заменяет его разностью этого значения и аргумента

i
, применяя стандартные правила арифметики указателей, и возвращает старое значение.

Объявление

T* fetch_sub(

 ptrdiff_t i, memory_order order = memory_order_seq_cst)

 volatile noexcept;

T* fetch_sub(

 ptrdiff_t i, memory_order order = memory_order_seq_cst)

 noexcept;

Результат

Атомарно возвращает текущее значение

*this
и сохраняет в
*this
значение
old-value - i
.

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

Значение

*this
непосредственно перед сохранением.

Исключения

Нет.

Примечание. Это атомарная операция чтения-модификации-записи для ячейки памяти, содержащей

*this
.


              STD::ATOMIC_FETCH_SUB
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно читает значение из экземпляра

atomic
и заменяет его разностью этого значения и аргумента
i
, применяя стандартные правила арифметики указателей.

Объявление

T* atomic_fetch_sub(

 volatile atomic* p, ptrdiff_t i) noexcept;

T* atomic_fetch_sub(atomic* p, ptrdiff_t i) noexcept;

Результат

return p->fetch_sub(i);


              STD::ATOMIC_FETCH_SUB_EXPLICIT
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Атомарно читает значение из экземпляра

atomic
и заменяет его разностью этого значения и аргумента
i
, применяя стандартные правила арифметики указателей.

Объявление

T* atomic_fetch_sub_explicit(

 volatile atomic* p, ptrdiff_t i, memory_order order)

 noexcept;

T* atomic_fetch_sub_explicit(

 atomic* p, ptrdiff_t i, memory_order order) noexcept;

Результат

return p->fetch_sub(i, order);


              STD::ATOMIC::OPERATOR++
            
, ОПЕРАТОР ПРЕДИНКРЕМЕНТА

Атомарно инкрементирует значение, хранящееся в

*this
, применяя стандартные правила арифметики указателей, и возвращает новое значение.

Объявление

T* operator++() volatile noexcept;

T* operator++() noexcept;

Результат

return this->fetch_add(1) + 1;


              STD::ATOMIC::OPERATOR++
            
, ОПЕРАТОР ПОСТИНКРЕМЕНТА

Атомарно инкрементирует значение, хранящееся в

*this
, и возвращает старое значение.

Объявление

T* operator++(int) volatile noexcept;

T* operator++(int) noexcept;

Результат

return this->fetch_add(1);


              STD::ATOMIC::OPERATOR--
            
, ОПЕРАТОР ПРЕДЕКРЕМЕНТА

Атомарно декрементирует значение, хранящееся в

*this
, применяя стандартные правила арифметики указателей, и возвращает новое значение.

Объявление

T* operator--() volatile noexcept;

T* operator--() noexcept;

Результат

return this->fetch_sub(1) - 1;


              STD::ATOMIC::OPERATOR--
            
, ОПЕРАТОР ПОСТДЕКРЕМЕНТА

Атомарно декрементирует значение, хранящееся в

*this
, применяя стандартные правила арифметики указателей, и возвращает старое значение.

Объявление

T* operator--(int) volatile noexcept;

T* operator--(int) noexcept;

Результат

return this->fetch_sub(1);


              STD::ATOMIC::OPERATOR+=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Атомарно складывает значение аргумента со значением, хранящимся в

*this
, применяя стандартные правила арифметики указателей, и возвращает новое значение.

Объявление

T* operator+=(ptrdiff_t i) volatile noexcept;

T* operator+=(ptrdiff_t i) noexcept;

Результат

return this->fetch_add(i) + i;


              STD::ATOMIC::OPERATOR-=
            
, СОСТАВНОЙ ОПЕРАТОР ПРИСВАИВАНИЯ

Атомарно вычитает значение аргумента из значения, хранящегося в

*this
, применяя стандартные правила арифметики указателей, и возвращает новое значение.

Объявление

T* operator-=(ptrdiff_t i) volatile noexcept;

T* operator-=(ptrdiff_t i) noexcept;

Результат

return this->fetch_sub(i) - i;

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

В заголовке

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

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

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. Заголовок

В заголовке

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

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

namespace std {

class mutex;

class recursive_mutex;

class timed_mutex;

class recursive_timed_mutex;


struct adopt_lock_t;

struct defer_lock_t;

struct try_to_lock_t;


constexpr adopt_lock_t adopt_lock{};

constexpr defer_lock_t defer_lock{};

constexpr try_to_lock_t try_to_lock{};


template

class lock_guard;


template

class unique_lock;


template

void lock(LockableType1& m1, LockableType2& m2...);


template

int try_lock(LockableType1& m1, LockableType2& m2...);


struct once_flag;


template

void call_once(once_flag& flag, Callable func, Args args...);

}

D.5.1. Класс
std::mutex

Класс

std::mutex
предоставляет базовые средства взаимного исключения и синхронизации потоков, применяемые для защиты разделяемых данных. Перед тем как обращаться к данным, защищаемым мьютексом, этот мьютекс необходимо захватить (или заблокировать), вызвав функцию
lock()
или
try_lock()
. В любой момент времени удерживать мьютекс может только один поток; если другой поток попытается захватить тот же мьютекс, то функция
try_lock()
вернет ошибку, а функция
lock()
приостановит выполнение потока. Закончив операции над разделяемыми данными, поток должен вызвать функцию
unlock()
, чтобы освободить мьютекс и дать другим потокам возможность захватить его.

Экземпляр

std::mutex
удовлетворяет требованиям концепции
Lockable
.

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

class mutex {

public:

 mutex(mutex const&)=delete;

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


 constexpr mutex() noexcept;

 ~mutex();


 void lock();

 void unlock();

 bool try_lock();

};


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

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

std::mutex
.

Объявление

constexpr mutex() noexcept;

Результат

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

std::mutex
.

Постусловия

Вновь сконструированный объект

std::mutex
первоначально не захвачен.

Исключения

Нет.


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

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

std::mutex
.

Объявление

~mutex();

Предусловия

Объект

*this
не должен быть захвачен.

Результат

Уничтожает

*this
.

Исключения

Нет.


              STD::MUTEX::LOCK
            
, ФУНКЦИЯ-ЧЛЕН

Захватывает объект

std::mutex
для текущего потока.

Объявление

void lock();

Предусловия

Вызывающий поток не должен удерживать мьютекс

*this
.

Результат

Блокирует текущий поток, пока мьютекс

*this
не будет захвачен.

Постусловия

*this
захвачен текущим потоком.

Исключения

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

std::system_error
в случае ошибки.


              STD::MUTEX::TRY_LOCK
            
, ФУНКЦИЯ-ЧЛЕН

Пытается захватить объект

std::mutex
для текущего потока.

Объявление

bool try_lock();

Предусловия

Вызывающий поток не должен удерживать мьютекс

*this
.

Результат

Пытается захватить объект

std::mutex
для текущего потока без блокирования.

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

true
, если вызывающий поток захватил мьютекс, иначе
false
.

Постусловия

*this
захвачен вызывающим потоком, если функция вернула
true
.

Исключения

Нет.

Примечание. Функция может не захватить мьютекс (и вернуть

false
), даже если никакой другой поток не удерживает
*this
.


              STD::MUTEX::UNLOCK
            
, ФУНКЦИЯ-ЧЛЕН

Освобождает объект

std::mutex
, удерживаемый текущим потоком.

Объявление

void unlock();

Предусловия

Вызывающий поток должен удерживать мьютекс

*this
.

Результат

Освобождает мьютекс

std::mutex
, удерживаемый текущим потоком.

Если другие потоки были блокированы в ожидании

*this
, то один из них разблокируется.

Постусловия

*this
не захвачен вызывающим потоком.

Исключения

Нет.

D.5.2. Класс
std::recursive_mutex

Класс

std::recursive_mutex
предоставляет базовые средства взаимного исключения и синхронизации потоков, применяемые для защиты разделяемых данных. Перед тем как обращаться к данным, защищаемым мьютексом, этот мьютекс необходимо захватить (или заблокировать), вызвав функцию
lock()
или
try_lock()
. В любой момент времени удерживать мьютекс может только один поток; если другой поток попытается захватить тот же мьютекс, то функция
try_lock()
вернет ошибку, а функция
lock()
приостановит выполнение потока. Закончив операции над разделяемыми данными, поток должен вызвать функцию
unlock()
, чтобы освободить мьютекс и дать другим потокам возможность захватить его.

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

std::recursive_mutex
, может снова обратиться к функции
lock()
или
try_lock()
, что приведёт к увеличению счетчика захватов. Никакой другой поток не сможет захватить этот мьютекс, пока владеющий им поток не вызовет функцию
unlock
столько раз, сколько было успешных вызовов
lock()
или
try_lock()
.

Экземпляр

std::recursive_mutex
удовлетворяет требованиям концепции
Lockable
.

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

class recursive_mutex {

public:

 recursive_mutex(recursive_mutex const&) = delete;

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

 recursive_mutex() noexcept;

 ~recursive_mutex();


 void lock();

 void unlock();

 bool try_lock() noexcept;

};


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

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

std::recursive_mutex
.

Объявление

recursive_mutex() noexcept;

Результат

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

std::recursive_mutex
.

Постусловия

Вновь сконструированный объект

std::recursive_mutex
первоначально не захвачен.

Исключения

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

std::system_error
, если не удалось создать экземпляр
std::recursive_mutex
.


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

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

std::recursive_mutex
.

Объявление

~recursive_mutex();

Предусловия

Объект

*this
не должен быть захвачен.

Результат

Уничтожает

*this
.

Исключения

Нет.


              STD::RECURSIVE_MUTEX::LOCK
            
, ФУНКЦИЯ-ЧЛЕН

Захватывает объект

std::recursive_mutex
для текущего потока.

Объявление

void lock();

Результат

Блокирует текущий поток, пока мьютекс

*this
не будет захвачен.

Постусловия

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

Исключения

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

std::system_error
в случае ошибки.


              STD::RECURSIVE_MUTEX::TRY_LOCK
            
, ФУНКЦИЯ-ЧЛЕН

Пытается захватить объект

std::recursive_mutex
для текущего потока.

Объявление

bool try_lock() noexcept;

Результат

Пытается захватить объект

std::recursive_mutex
для текущего потока без блокирования.

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

true
, если вызывающий поток захватил мьютекс, иначе
false
.

Постусловия

*this
захвачен вызывающим потоком, если функция вернула
true
.

Исключения

Нет.

Примечание. Если вызывающий поток уже удерживал

*this
, то функция возвращает
true
, и счетчик захватов
*this
текущим потоком увеличивается на единицу. Если текущий поток не удерживал
*this
, то функция может не захватить мьютекс (и вернуть
false
), даже если никакой другой поток не удерживает
*this
.


              STD::RECURSIVE_MUTEX::UNLOCK
            
, ФУНКЦИЯ-ЧЛЕН

Освобождает объект

std::recursive_mutex
, удерживаемый текущим потоком.

Объявление

void unlock();

Предусловия

Вызывающий поток должен удерживать мьютекс

*this
.

Результат

Освобождает мьютекс

std::recursive_mutex
, удерживаемый текущим потоком. Если это последний захват
*this
данным потоком, и другие потоки были блокированы в ожидании
*this
, то один из них разблокируется.

Постусловия

Количество захватов

*this
вызывающим потоком, уменьшается на единицу.

Исключения

Нет.

D.5.3. Класс
std::timed_mutex

Класс

std::timed_mutex
предоставляет поддержку блокировок с таймаутами сверх базовых средств взаимного исключения и синхронизации, предоставляемых классом
std::mutex
. Перед тем как обращаться к данным, защищаемым мьютексом, этот мьютекс необходимо захватить (или заблокировать), вызвав функцию l
ock()
,
try_lock()
,
try_lock_for()
или
try_lock_until()
. Если мьютекс уже захвачен другим потоком, то функция
try_lock()
вернет ошибку, функция
lock()
приостановит выполнение потока до получения мьютекса, а функции
try_lock_for()
и
try_lock_until()
приостановят выполнение потока до получения мьютекса или истечения таймаута. Закончив операции над разделяемыми данными, поток должен вызвать функцию
unlock()
(вне зависимости от того, какой функцией мьютекс был захвачен), чтобы освободить мьютекс и дать другим потокам возможность захватить его.

Экземпляр

std::timed_mutex
удовлетворяет требованиям концепции
TimedLockable
.

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

class timed_mutex {

public:

 timed_mutex(timed_mutex const&)=delete;

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

 timed_mutex();

 ~timed_mutex();


 void lock();

 void unlock();

 bool try_lock();


 template

 bool try_lock_for(

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


 template

 bool try_lock_until(

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

};


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

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

std::timed_mutex
.

Объявление

timed_mutex();

Результат

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

std::timed_mutex
.

Постусловия

Вновь сконструированный объект

std::timed_mutex
первоначально не захвачен.

Исключения

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

std::system_error
, если не удалось создать экземпляр
std::timed_mutex
.


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

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

std::timed_mutex
.

Объявление

~timed_mutex();

Предусловия

Объект

*this
не должен быть захвачен.

Результат

Уничтожает

*this
.

Исключения

Нет.


              STD::TIMED_MUTEX::LOCK
            
, ФУНКЦИЯ-ЧЛЕН

Захватывает объект

std::timed_mutex
для текущего потока.

Объявление

void lock();

Предусловия

Вызывающий поток не должен удерживать мьютекс

*this

Результат

Блокирует текущий поток, пока мьютекс

*this
не будет захвачен.

Постусловия

*this
захвачен текущим потоком.

Исключения

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

std::system_error
в случае ошибки.


              STD::TIMED_MUTEX::TRY_LOCK
            
, ФУНКЦИЯ-ЧЛЕН

Пытается захватить объект

std::timed_mutex
для текущего потока.

Объявление

bool try_lock();

Предусловия

Вызывающий поток не должен удерживать мьютекс

*this
.

Результат

Пытается захватить объект

std::timed_mutex
для текущего потока без блокирования.

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

true
, если вызывающий поток захватил мьютекс, иначе
false
.

Постусловия

*this
захвачен вызывающим потоком, если функция вернула
true
.

Исключения

Нет.

Примечание. Функция может не захватить мьютекс (и вернуть

false
), даже если никакой другой поток не удерживает
*this
.


              STD::TIMED_MUTEX::TRY_LOCK_FOR
            
, ФУНКЦИЯ-ЧЛЕН

Пытается захватить объект

std::timed_mutex
для текущего потока.

Объявление

template

bool try_lock_for(

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

Предусловия

Вызывающий поток не должен удерживать мьютекс

*this
.

Результат

Пытается захватить объект

std::timed_mutex
для текущего потока в течение времени, заданного аргументом
relative_time
. Если
relative_time.count()
равно нулю или отрицательно, то функция возвращается немедленно, как если бы это был вызов
try_lock()
. В противном случае вызывающий поток приостанавливается до получения мьютекса или до истечения времени, заданного аргументом
relative_time
.

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

true
, если вызывающий поток захватил мьютекс, иначе
false
.

Постусловия

*this
захвачен вызывающим потоком, если функция вернула
true
.

Исключения

Нет.

Примечание. Функция может не захватить мьютекс (и вернуть

false
), даже если никакой другой поток не удерживает
*this
. Поток может быть блокирован дольше, чем указано. Если возможно, истекшее время измеряется по стабильным часам.


              STD::TIMED_MUTEX::TRY_LOCK_UNTIL
            
, ФУНКЦИЯ-ЧЛЕН

Пытается захватить объект

std::timed_mutex
для текущего потока.

Объявление

template

bool try_lock_until(

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

Предусловия

Вызывающий поток не должен удерживать мьютекс

*this
.

Результат

Пытается захватить объект

std::timed_mutex
для текущего потока, пока не наступит момент времени, заданный аргументом
absolute_time
. Если в момент вызова
absolute_time <= Clock::now()
, то функция возвращается немедленно, как если бы это был вызов
try_lock()
. В противном случае вызывающий поток приостанавливается до получения мьютекса или до наступления момента времени, большего или равного
absolute_time
.

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

true
, если вызывающий поток захватил мьютекс, иначе
false
.

Постусловия

*this
захвачен вызывающим потоком, если функция вернула
true
.

Исключения

Нет.

Примечание. Функция может не захватить мьютекс (и вернуть

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


              STD::TIMED_MUTEX::UNLOCK
            
, ФУНКЦИЯ-ЧЛЕН

Освобождает объект

std::timed_mutex
, удерживаемый текущим потоком.

Объявление

void unlock();

Предусловия

Вызывающий поток должен удерживать мьютекс

*this
.

Результат

Освобождает мьютекс

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

Постусловия

*this
не захвачен вызывающим потоком.

Исключения

Нет.

D.5.4. Класс
std::recursive_timed_mutex

Класс

std::recursive_timed_mutex
предоставляет поддержку блокировок с таймаутами сверх базовых средств взаимного исключения и синхронизации, предоставляемых классом
std::recursive_mutex
. Перед тем как обращаться к данным, защищаемым мьютексом, этот мьютекс необходимо захватить (или заблокировать), вызвав функцию
lock()
,
try_lock()
,
try_lock_for()
или
try_lock_until()
. Если мьютекс уже захвачен другим потоком, то функция
try_lock()
вернет ошибку, функция
lock()
приостановит выполнение потока до получения мьютекса, а функции
try_lock_for()
и
try_lock_until()
приостановят выполнение потока до получения мьютекса или истечения таймаута. Закончив операции над разделяемыми данными, поток должен вызвать функцию
unlock()
(вне зависимости от того, какой функцией мьютекс был захвачен), чтобы освободить мьютекс и дать другим потокам возможность захватить его.

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

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

Экземпляр

std::recursive_timed_mutex
удовлетворяет требованиям концепции
TimedLockable
.

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

class recursive_timed_mutex {

public:

 recursive_timed_mutex(recursive_timed_mutex const&)=delete;

 recursive_timed_mutex& operator=(

  recursive_timed_mutex const&)=delete;


 recursive_timed_mutex();

 ~recursive_timed_mutex();


 void lock();

 void unlock();

 bool try_lock() noexcept;


 template

 bool try_lock_for(

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


 template

 bool try_lock_until(

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

};


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

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

std::recursive_timed_mutex
.

Объявление

recursive_timed_mutex();

Результат

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

std::recursive_timed_mutex
.

Постусловия

Вновь сконструированный объект

std::recursive_timed_mutex
первоначально не захвачен.

Исключения

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

std::system_error
, если не удалось создать экземпляр
std::recursive_timed_mutex
.


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

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

std::recursive_timed_mutex
.

Объявление

~recursive_timed_mutex();

Предусловия

Объект

*this
не должен быть захвачен.

Результат

Уничтожает

*this
.

Исключения

Нет.


              STD::RECURSIVE_TIMED_MUTEX::LOCK
            
, ФУНКЦИЯ-ЧЛЕН

Захватывает объект

std::recursive_timed_mutex
для текущего потока.

Объявление

void lock();

Результат

Блокирует текущий поток, пока мьютекс

*this
не будет захвачен.

Постусловия

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

Исключения

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

std::system_error
в случае ошибки.


              STD::RECURSIVE_TIMED_MUTEX::TRY_LOCK
            
, ФУНКЦИЯ-ЧЛЕН

Пытается захватить объект

std::recursive_timed_mutex
для текущего потока.

Объявление

bool try_lock() noexcept;

Результат

Пытается захватить объект

std::recursive_timed_mutex
для текущего потока без блокирования.

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

true
, если вызывающий поток захватил мьютекс, иначе
false
.

Постусловия

*this
захвачен вызывающим потоком, если функция вернула
true
.

Исключения

Нет.

Примечание. Если вызывающий поток уже удерживал

*this
, то функция возвращает
true
, и счетчик захватов
*this
текущим потоком увеличивается на единицу. Если текущий поток не удерживал
*this
, то функция может не захватить мьютекс (и вернуть
false
), даже если никакой другой поток не удерживает
*this
.


              STD::RECURSIVE_TIMED_MUTEX::TRY_LOCK_FOR
            
, ФУНКЦИЯ-ЧЛЕН

Пытается захватить объект

std::recursive_timed_mutex
для текущего потока.

Объявление

template

bool try_lock_for(

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

Результат

Пытается захватить объект

std::recursive_timed_mutex
для текущего потока в течение времени, заданного аргументом
relative_time
. Если
relative_time.count()
равно нулю или отрицательно, то функция возвращается немедленно, как если бы это был вызов
try_lock()
. В противном случае вызывающий поток приостанавливается до получения мьютекса или до истечения времени, заданного аргументом
relative_time
.

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

true
, если вызывающий поток захватил мьютекс, иначе
false
.

Постусловия

*this
захвачен вызывающим потоком, если функция вернула
true
.

Исключения

Нет.

Примечание. Если вызывающий поток уже удерживал

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


              STD::RECURSIVE_TIMED_MUTEX::TRY_LOCK_UNTIL
            
, ФУНКЦИЯ-ЧЛЕН

Пытается захватить объект

std::recursive_timed_mutex
для текущего потока.

Объявление

template

bool try_lock_until(

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

Результат

Пытается захватить объект

std::recursive_timed_mutex
для текущего потока, пока не наступит момент времени, заданный аргументом
absolute_time
. Если в момент вызова
absolute_time <= Clock::now()
, то функция возвращается немедленно, как если бы это был вызов
try_lock()
. В противном случае вызывающий поток приостанавливается до получения мьютекса или до наступления момента времени, большего или равного
absolute_time
.

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

true
, если вызывающий поток захватил мьютекс, иначе
false
.

Постусловия

*this
захвачен вызывающим потоком, если функция вернула
true
.

Исключения

Нет.

Примечание. Если вызывающий поток уже удерживал

*this
, то функция возвращает
true
, и счетчик захватов
*this
текущим потоком увеличивается на единицу. Если текущий поток не удерживал
*this
, то функция может не захватить мьютекс (и вернуть
false
), даже если никакой другой поток не удерживает
*this
. Не дается никаких гарантий относительно того, сколько времени будет блокирован вызывающий поток. Гарантируется лишь, что если функция вернула
false
, то значение, возвращенное
Clock::now()
, больше или равно
absolute_time
в точке, где поток разблокировался.


              STD::RECURSIVE_TIMED_MUTEX::UNLOCK
            
, ФУНКЦИЯ-ЧЛЕН

Освобождает объект

std::recursive_timed_mutex
, удерживаемый текущим потоком.

Объявление

void unlock();

Предусловия

Вызывающий поток должен удерживать мьютекс

*this
.

Результат

Освобождает мьютекс

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

Постусловия

Количество захватов

*this
вызывающим потоком, уменьшается на единицу.

Исключения

Нет.

D.5.5. Шаблон класса
std::lock_guard

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

std::lock_guard
предоставляет простую обертку владения блокировкой. Тип блокируемого мьютекса задается параметром шаблона
Mutex
и должен удовлетворять требованиям концепции
Lockable
. Заданный мьютекс захватывается в конструкторе и освобождается в деструкторе. Тем самым мы получаем простое средство захвата мьютекса в некотором блоке кода, которое гарантирует освобождение мьютекса при выходе из блока вне зависимости от того, как этот выход произведен: по достижении закрывающей скобки, в результате предложения, меняющего поток управления, например
break
или
return
, или вследствие исключения.

Экземпляры

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

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

template 

class lock_guard {

public:

 typedef Mutex mutex_type;


 explicit lock_guard(mutex_type& m);

 lock_guard(mutex_type& m, adopt_lock_t);

 ~lock_guard();


 lock_guard(lock_guard const&) = delete;

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

};


              STD::LOCK_GUARD
            
, ЗАХВАТЫВАЮЩИЙ КОНСТРУКТОР

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

std::lock_guard
, который захватывает указанный мьютекс.

Объявление

explicit lock_guard(mutex_type& m);

Результат

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

std::lock_guard
, который ссылается на указанный мьютекс. Вызывает
m.lock()
.

Исключения

Любое исключение, возбуждаемое

m.lock()
.

Постусловия

*this
владеет блокировкой
m
.


              STD::LOCK_GUARD
            
, КОНСТРУКТОР, ПЕРЕНИМАЮЩИЙ БЛОКИРОВКУ

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

std::lock_guard
, который владеет блокировкой указанного мьютекса.

Объявление

lock_guard(mutex_type& m, std::adopt_lock_t);

Предусловия

Вызывающий поток должен владеть блокировкой

m
.

Результат

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

std::lock_guard
, который ссылается на указанный мьютекс и принимает владение блокировкой
m
, удерживаемой вызывающим потоком.

Исключения

Нет.

Постусловия

*this
владеет блокировкой
m
, удерживаемой вызывающим потоком.


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

Уничтожает экземпляр

std::lock_guard
и освобождает соответствующий мьютекс.

Объявление

~lock_guard();

Результат

Вызывает

m.unlock()
для мьютекса
m
, заданного при конструировании
*this
.

Исключения

Нет.

D.5.6. Шаблон класса
std::unique_lock

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

std::unique_lock
предоставляет более общую обертку владения блокировкой, чем
std::lock_guard
. Тип блокируемого мьютекса задается параметром шаблона
Mutex
и должен удовлетворять требованиям концепции
BasicLockable
. Вообще говоря, заданный мьютекс захватывается в конструкторе и освобождается в деструкторе, хотя имеются также дополнительные конструкторы и функции-члены, предлагающие другие возможности. Тем самым мы получаем средство захвата мьютекса в некотором блоке кода, которое гарантирует освобождение мьютекса при выходе из блока вне зависимости от того, как этот выход произведен: по достижении закрывающей скобки, в результате предложения, меняющего поток управления, например
break
или
return
, или вследствие исключения.

Функции ожидания в классе

std::condition_variable
требуют объекта
std::unique_lock
, и любая конкретизация шаблона
std::unique_lock
может быть использована в качестве параметра типа
Lockable
в любом варианте функции
wait
из класса
std::condition_variable_any
.

Если тип

Mutex
удовлетворяет требованиям концепции
Lockable
, то им удовлетворяет и тип
std::unique_lock
. Если, кроме того, тип
Mutex
удовлетворяет требованиям концепции
TimedLockable
, то им удовлетворяет и тип
std::unique_lock
.

Экземпляры

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

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

template 

class unique_lock {

public:

 typedef Mutex mutex_type;


 unique_lock() noexcept;

 explicit unique_lock(mutex_type& m);

 unique_lock(mutex_type& m, adopt_lock_t);

 unique_lock(mutex_type& m, defer_lock_t) noexcept;

 unique_lock(mutex_type& m, try_to_lock_t);


 template

 unique_lock(

  mutex_type& m,

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


 template

 unique_lock(

  mutex_type& m,

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


 ~unique_lock();

 unique_lock(unique_lock const&) = delete;

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


 unique_lock(unique_lock&&);

 unique_lock& operator=(unique_lock&&);


 void swap(unique_lock& other) noexcept;


 void lock();

 bool try_lock();

 template

 bool try_lock_for(

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

 template

 bool try_lock_until(

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

 void unlock();


 explicit operator bool() const noexcept;

 bool owns_lock() const noexcept;

 Mutex* mutex() const noexcept;

 Mutex* release() noexcept;

};


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

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

std::unique_lock
, с которым не ассоциирован мьютекс.

Объявление

unique_lock() noexcept;

Результат

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

std::unique_lock
, с которым не ассоциирован мьютекс.

Постусловия

this->mutex() == NULL
,
this->owns_lock() == false
.


              STD::UNIQUE_LOCK
            
, ЗАХВАТЫВАЮЩИЙ КОНСТРУКТОР

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

std::unique_lock
, который захватывает указанный мьютекс.

Объявление

explicit unique_lock(mutex_type& m);

Результат

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

std::unique_lock
, который ссылается на указанный мьютекс.
Вызывает m.lock()
.

Исключения

Любое исключение, возбуждаемое

m.lock()
.

Постусловия

this->owns_lock() == true
,
this->mutex() == &m
.


              STD::UNIQUE_LOCK
            
, КОНСТРУКТОР, ПЕРЕНИМАЮЩИЙ БЛОКИРОВКУ

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

std::unique_lock
, который владеет блокировкой указанного мьютекса.

Объявление

unique_lock(mutex_type& m, std::adopt_lock_t);

Предусловия

Вызывающий поток должен владеть блокировкой

m
.

Результат

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

std::unique_lock
, который ссылается на указанный мьютекс и принимает владение блокировкой
m
, удерживаемой вызывающим потоком.

Исключения

Нет.

Постусловия

this->owns_lock() == true
,
this->mutex() == &m
.


              STD::UNIQUE_LOCK
            
, КОНСТРУКТОР ОТЛОЖЕННОЙ БЛОКИРОВКИ

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

std::unique_lock
, который не владеет блокировкой указанного мьютекса.

Объявление

unique_lock(mutex_type& m, std::defer_lock_t) noexcept;

Результат

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

std::unique_lock
, который ссылается на указанный мьютекс.

Исключения

Нет.

Постусловия

this->owns_lock() == false
,
this->mutex() == &m
.


              STD::UNIQUE_LOCK
            
, КОНСТРУКТОР ПРОБНОЙ БЛОКИРОВКИ

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

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

Объявление

unique_lock(mutex_type& m, std::try_to_lock_t);

Предусловия

Тип

Mutex
, которым конкретизирован шаблон
std::unique_lock
, должен удовлетворять требованиям концепции
Lockable
.

Результат

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

std::unique_lock
, который ссылается на указанный мьютекс. Вызывает
m.try_lock()
.

Исключения

Нет.

Постусловия

this->owns_lock()
возвращает результат вызова
m.try_lock()
,
this->mutex() == &m
.


              STD::UNIQUE_LOCK
            
, КОНСТРУКТОР ПРОБНОЙ БЛОКИРОВКИ С ОТНОСИТЕЛЬНЫМ ТАЙМАУТОМ

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

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

Объявление

template

unique_lock(

 mutex_type& m,

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

Предусловия

Тип

Mutex
, которым конкретизирован шаблон
std::unique_lock
, должен удовлетворять требованиям концепции
TimedLockable
.

Результат

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

std::unique_lock
, который ссылается на указанный мьютекс. Вызывает
m.try_lock_for(relative_time)
.

Исключения

Нет.

Постусловия

this->owns_lock()
возвращает результат вызова
m.try_lock_for()
,
this->mutex() == &m
.


              STD::UNIQUE_LOCK
            
, КОНСТРУКТОР ПРОБНОЙ БЛОКИРОВКИ С АБСОЛЮТНЫМ ТАЙМАУТОМ

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

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

Объявление

template

unique_lock(

 mutex_type& m,

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

Предусловия

Тип

Mutex
, которым конкретизирован шаблон
std::unique_lock
, должен удовлетворять требованиям концепции
TimedLockable
.

Результат

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

std::unique_lock
, который ссылается на указанный мьютекс. Вызывает
m.try_lock_until(relative_time)
.

Исключения

Нет.

Постусловия

this->owns_lock()
возвращает результат вызова
m.try_lock_until()
,
this->mutex() == &m
.


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

Передает владение блокировкой от существующего объекта

std::unique_lock
вновь сконструированному.

Объявление

unique_lock(unique_lock&& other) noexcept;

Результат

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

std::unique_lock
. Если объект
other
владел блокировкой мьютекса до вызова конструктора, то теперь этой блокировкой владеет вновь сконструированный объект
std::unique_lock
.

Постусловия

Для вновь сконструированного объекта

std::unique_lock x
,
x.mutex()
равно значению
other.mutex()
до вызова конструктора, а
x.owns_lock()
равно значению
other.owns_lock()
до вызова конструктора.
other.mutex() == NULL
,
other.owns_lock() == false
.

Исключения

Нет.

Примечание. Объекты

std::unique_lock
не удовлетворяют требованиям концепции
CopyConstructible
, поэтому копирующего конструктора не существует, существует только этот перемещающий конструктор.


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

Передает владение блокировкой от одного объекта

std: :unique_ lock
другому.

Объявление

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

Результат

Если

this->owns_lock()
возвращала
true
до вызова этого оператора, то вызывает
this->unlock()
. Если объект
other
владел блокировкой мьютекса до присваивания, то теперь этой блокировкой владеет
*this
.

Постусловия

this.mutex()
равно значению
other.mutex()
до присваивания, а
this.owns_lock()
равно значению
other.owns_lock()
до присваивания.
other.mutex() == NULL
,
other.owns_lock() == false
.

Исключения

Нет.

Примечание. Объекты

std::unique_lock
не удовлетворяют требованиям концепции
CopyAssignable
, поэтому копирующего оператора присваивания не существует, существует только этот перемещающий оператор присваивания.


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

Уничтожает экземпляр

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

Объявление

~unique_lock();

Результат

Если

this->owns_lock()
возвращает
true
, то вызывает
this->mutex()->unlock()
.

Исключения

Нет.


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

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

std::unique_lock
.

Объявление

void swap(unique_lock& other) noexcept;

Результат

Если

other
владел блокировкой мьютекса до вызова, то теперь этой блокировкой владеет
*this
. Если
*this
владел блокировкой мьютекса до вызова, то теперь этой блокировкой владеет
other
.

Постусловия

this.mutex()
равно значению
other.mutex()
до вызова,
other.mutex()
равно значению
this.mutex()
до вызова,
this.owns_lock()
равно значению
other.owns_lock()
до вызова,
other.owns_lock()
равно значению
this.owns_lock()
до вызова.

Исключения

Нет.


              STD::SWAP
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

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

std::unique_lock
.

Объявление

void swap(unique_lock& lhs, unique_lock& rhs) noexcept;

Результат

lhs.swap(rhs)

Исключения

Нет.


              STD::UNIQUE_LOCK::LOCK
            
, ФУНКЦИЯ-ЧЛЕН

Захватывает мьютекс, ассоциированный с

*this
.

Объявление

void lock();

Предусловия

this->mutex() != NULL
,
this->owns_lock() == false
.

Результат

Вызывает

this->mutex()->lock()
.

Исключения

Любое исключение, возбужденное

this->mutex()->lock()
. Исключение типа
std::system_error
с кодом ошибки
std::errc::operation_not_permitted
, если
this->mutex() == NULL
. Исключение типа
std::system_error
с кодом ошибки
std::errc::resource_deadlock_would_occur
, если
this->owns_lock() == true
в момент вызова.

Постусловия

this->owns_lock() == true
.


              STD::UNIQUE_LOCK::TRY_LOCK
            
, ФУНКЦИЯ-ЧЛЕН

Пытается захватить мьютекс, ассоциированный с

*this
.

Объявление

bool try_lock();

Предусловия

Тип

Mutex
, которым конкретизируется шаблон
std::unique_lock
, должен удовлетворять требованиям концепции
Lockable
.
this->mutex() != NULL
,
this->owns_lock() == false
.

Результат

Вызывает

this->mutex ()->try_lock()
.

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

true
, если вызов
this->mutex()->try_lock()
вернул
true
, иначе
false
.

Исключения

Любое исключение, возбужденное

this->mutex()->try_lock()
. Исключение типа
std::system_error
с кодом ошибки
std::errc::operation_not_permitted
, если
this->mutex() == NULL
. Исключение типа
std::system_error
с кодом ошибки
std::errc::resource_deadlock_would_occur
, если
this->owns_lock() == true
в момент вызова.

Постусловия

Если функция возвращает

true
, то
this->owns_lock() == true
, иначе
this->owns_lock() == false
.


              STD::UNIQUE_LOCK::UNLOCK
            
, ФУНКЦИЯ-ЧЛЕН

Освобождает мьютекс, ассоциированный с

*this
.

Объявление

void unlock();

Предусловия

this->mutex() != NULL
,
this->owns_lock() == true
.

Результат

Вызывает

this->mutex()->unlock()
.

Исключения

Любое исключение, возбужденное

this->mutex()->unlock()
. Исключение типа
std::system_error
с кодом ошибки
std::errc::operation_not_permitted
, если
this->owns_lock() == false
в момент вызова.

Постусловия

this->owns_lock() == false
.


              STD::UNIQUE_LOCK::TRY_LOCK_FOR
            
, ФУНКЦИЯ-ЧЛЕН

Пытается захватить мьютекс, ассоциированный с

*this
, в течение указанного времени.

Объявление

template

bool try_lock_for(

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

Предусловия

Тип

Mutex
, которым конкретизируется шаблон
std::unique_lock
, должен удовлетворять требованиям концепции
TimedLockable
.
this->mutex() != NULL
,
this->owns_lock() == false
.

Результат

Вызывает

this->mutex ()->try_lock_for(relative_time)
.

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

true
, если вызов
this->mutex()->try_lock_for()
вернул
true
, иначе
false
.

Исключения

Любое исключение, возбужденное

this->mutex()->try_lock_for()
. Исключение типа
std::system_error
с кодом ошибки
std::errc::operation_not_permitted
, если
this->mutex() == NULL
. Исключение типа
std::system_error
с кодом ошибки
std::errc::resource_deadlock_would_occur
, если
this->owns_lock() == true
в момент вызова.

Постусловия

Если функция вернула

true
, то
this->owns_lock() == true
, иначе
this->owns_lock() == false
.


              STD::UNIQUE_LOCK::TRY_LOCK_UNTIL
            
, ФУНКЦИЯ-ЧЛЕН

Пытается захватить мьютекс, ассоциированный с

*this
, в течение указанного времени.

Объявление

template

bool try_lock_until(

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

Предусловия

Тип

Mutex
, которым конкретизируется шаблон
std::unique_lock
, должен удовлетворять требованиям концепции
TimedLockable
.
this->mutex() != NULL
,
this->owns_lock() == false
.

Результат

Вызывает

this->mutex()->try_lock_until(absolute_time)
.

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

true
, если вызов
this->mutex()->try_lock_until()
вернул
true
, иначе
false
.

Исключения

Любое исключение, возбужденное

this->mutex()->try_lock_until()
. Исключение типа
std::system_error
с кодом ошибки
std::errc::operation_not_permitted
, если
this->mutex() == NULL
. Исключение типа
std::system_error
с кодом ошибки
std::errc::resource_deadlock_would_occur
, если
this->owns_lock() == true
в момент вызова.

Постусловия

Если функция вернула

true
, то
this->owns_lock() == true
, иначе
this->owns_lock() == false
.


              STD::UNIQUE_LOCK::OPERATOR BOOL
            
, ФУНКЦИЯ-ЧЛЕН

Проверяет, владеет ли

*this
блокировкой мьютекса.

Объявление

explicit operator bool() const noexcept;

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

this->owns_lock()
. Исключения

Нет.

Примечание. Это оператор явного преобразования, поэтому он вызывается неявно только в контекстах, где результат используется как булевское значение, а не тогда, когда результат трактуется как целое, равное 0 или 1.


              STD::UNIQUE_LOCK::OWNS_LOCK
            
, ФУНКЦИЯ-ЧЛЕН

Проверяет, владеет ли

*this
блокировкой мьютекса.

Объявление

bool owns_lock() const noexcept;

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

true
, если
*this
владеет блокировкой мьютекса, иначе
false
.

Исключения

Нет.


              STD::UNIQUE_LOCK::MUTEX
            
, ФУНКЦИЯ-ЧЛЕН

Возвращает мьютекс, ассоциированный с

*this
, если таковой имеется.

Объявление

mutex_type* mutex() const noexcept;

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

Указатель на мьютекс, ассоциированный с

*this
, если таковой имеется, иначе
NULL
.

Исключения

Нет.


              STD::UNIQUE_LOCK::RELEASE
            
, ФУНКЦИЯ-ЧЛЕН

Возвращает мьютекс, ассоциированный с

*this
, если таковой имеется, и разрывает эту ассоциацию.

Объявление

mutex_type* release() noexcept;

Результат

Разрывает ассоциацию мьютекса с

*this
, не освобождая блокировку.

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

Указатель на мьютекс, ассоциированный с

*this
, если таковой имеется, иначе
NULL
.

Постусловия

this->mutex() == NULL
,
this->owns_lock() == false.

Исключения

Нет.

Примечание. Если

this->owns_lock()
вернула бы до этого обращения
true
, то с этого момента за освобождение мьютекса отвечает вызывающая программа.

D.5.7. Шаблон функции
std::lock

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

std::lock
предоставляет возможность захватить сразу несколько мьютексов, не опасаясь возникновения взаимоблокировки из-за несогласованного порядка захвата.

Объявление

template

void lock(LockableType1& m1, LockableType2& m2...);

Предусловия

Типы параметров

LockableType1
,
LockableType2
, … должны удовлетворять требованиям концепции
Lockable
.

Результат

Захватывает все объекты

m1
,
m2
, … допускающих блокировку типов, обращаясь к функциям-членам
lock()
,
try_lock()
и
unlock()
этих типов в порядке, который гарантированно не приводит к взаимоблокировкам, но в остальном не специфицирован.

Постусловия

Текущий поток захватывает все переданные в аргументах объекты.

Исключения

Любое исключение, возбуждаемое обращениями к функциям

lock()
,
try_lock()
и
unlock()
.

Примечание. Если исключение распространяется за пределы

std::lock
, то для любого объекта
m1
,
m2
, …, для которого в результате обращения к
lock()
или
try_lock()
была успешно получена блокировка, гарантированно будет вызвана функция
unlock()
.

D.5.8. Шаблон функции
std::try_lock

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

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

Объявление

template

int try_lock(LockableType1& m1, LockableType2& m2...);

Предусловия

Типы параметров

LockableType1
,
LockableType2
, … должны удовлетворять требованиям концепции
Lockable
.

Результат

Пытается захватить все объекты

m1
,
m2
, … допускающих блокировку типов, обращаясь по очереди к функции
try_lock()
каждого из них. Если
try_lock()
вернёт
false
или возбудит исключение, то уже захваченные блокировки освобождаются путем вызова функции
unlock()
соответствующего объекта.

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

-1, если были захвачены все блокировки (то есть все вызовы

try_lock()
вернули
true
), в противном случае начинающийся с нуля индекс объекта, для которого вызов
try_lock()
вернул
false
.

Постусловия

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

Исключения

Любое исключение, возбуждаемое обращениями к функции

try_lock
.

Примечание. Если исключение распространяется за пределы

std::try_lock
, то для любого объекта
m1
,
m2
, …, для которого в результате обращения к
try_lock()
была успешно получена блокировка, гарантированно будет вызвана функция
unlock()
.

D.5.9. Класс
std::once_flag

Экземпляры класса

std::once_flag
используются совместно с шаблоном функции
std::call_once
для гарантии того, что некая функция будет вызвала ровно один раз, даже если ее могут вызывать одновременно несколько потоков.

Экземпляры

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

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

struct once_flag {

 constexpr once_flag() noexcept;


 once_flag(once_flag const&) = delete;

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

};


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

Создает объект

std::once_flag
в состоянии, обозначающем, что ассоциированная функция еще не вызывалась.

Объявление

constexpr once_flag() noexcept;

Результат

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

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

D.5.10. Шаблон функции
std::call_once

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

std::call_once
используется совместно с объектом
std::once_flag
для гарантии того, что некая функция будет вызвала ровно один раз, даже если ее могут вызывать одновременно несколько потоков.

Объявление

template

void call_once(

 std::once_flag& flag, Callable func, Args args...);

Предусловия

Выражение

INVOKE(func, args)
допустимо для переданных значений
func
и
args
. Тип
Callable
и все члены
Args
удовлетворяют требованиям концепции
MoveConstructible
.

Результат

Обращения к

std::call_once
с одним и тем же объектом
std::once_flag
сериализуются. Если раньше не было результативного обращения к
std::call_once
с данным объектом
std::once_flag
, то аргумент
func
(или его копия) вызывается так, будто имело место обращение к
INVOKE(func, args)
, причем вызов
std::call_once
считается результативным тогда и только тогда, когда вызов
func
завершился без возбуждения исключения. Если имело место исключение, то оно передается вызывающей программе. Если ранее уже было результативное обращение к
std::call_once
с данным объектом
std::once_flag
, то новый вызов
std::call_once
возвращает управление, не вызывая
func
.

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

Возврат из результативного вызова

std::call_once
с объектом
std::once_flag
происходит-раньше всех последующих вызовов
std::call_once
с тем же объектом
std::once_flag
.

Исключения

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

std::system_error
, если желаемого эффекта добиться не удалось, или любое исключение, возбужденное при обращении к
func
.

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

В заголовке

объявлены средства для поддержки арифметических операций с рациональными числами на этапе компиляции.

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

namespace std {

template

class ratio;


// арифметические операции с рациональными числами

template 

using ratio_add = см. описание;


template 

using ratio_subtract = см. описание;


template 

using ratio_multiply = см. описание;


template 

using ratio_divide = см. описание;


// сравнение рациональных чисел

template 

struct ratio_equal;


template 

struct ratio_not_equal;


template 

struct ratio_less;


template 

struct ratio_less_equal;


template 

struct ratio_greater;


template 

struct ratio_greater_equal;


typedef ratio<1, 1000000000000000000> atto;

typedef ratio<1, 1000000000000000> femto;

typedef ratio<1, 1000000000000> pico;

typedef ratio<1, 1000000000> nano;

typedef ratio<1, 1000000> micro;

typedef ratio<1, 1000> milli;

typedef ratio<1, 100> centi;

typedef ratio<1, 10> deci;

typedef ratio<10, 1> deca;

typedef ratio<100, 1> hecto;

typedef ratio<1000, 1> kilo;

typedef ratio<1000000, 1> mega;

typedef ratio<1000000000, 1> giga;

typedef ratio<1000000000000, 1> tera;

typedef ratio<1000000000000000, 1> peta;

typedef ratio<1000000000000000000, 1> exa;

D.6.1. Шаблон класса
std::ratio

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

предоставляет механизм для выполнения на этапе компиляции арифметических операций с рациональными числами, например: деления пополам (
std::ratio<1, 2>
), нахождения двух третей (
std::ratio<2, 3>
) пятнадцати сорок третьих (
std::ratio<15, 43>
). В стандартной библиотеке С++ этот шаблон используется для задания периода при конкретизации шаблона класса
std::chrono::duration
.

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

template 

class ratio {

public:

 typedef ratio type;


 static constexpr intmax_t num = см. ниже;

 static constexpr intmax_t den = см. ниже;

};

Требования

D
не может быть равно нулю.

Описание

num
и
den
— соответственно числитель и знаменатель дроби
N/D
после сокращения без общих множителей. Значение
den
всегда положительно. Если
N
и
D
одного знака, то
num
положительно, иначе
num
отрицательно.

Примеры

ratio<4,6>::num == 2

ratio<4,6>::den == 3

ratio<4,-6>::num == -2

ratio<4,-6>::den == 3

D.6.2. Псевдоним шаблона
std::ratio_add

Псевдоним шаблона

std::ratio_add
предоставляет механизм сложения двух значений
std::ratio
на этапе компиляции с применением правил арифметических операций с рациональными числами.

Определение

template 

using ratio_add = std::ratio<см. ниже>;

Предусловия

R1
и
R2
должны быть конкретизациями шаблона
std::ratio
.

Результат

ratio_add
определяется как псевдоним конкретизации
std::ratio
, представляющий сумму дробей, представленных параметрами
R1
и
R2
, если эту сумму можно вычислить без переполнения. Если при вычислении возникает переполнение, то программа считается некорректной. В отсутствии переполнения
std::ratio_add
будет иметь такие же значения
num
и
den
, как в конкретизации
std::ratio
.

Примеры

std::ratio_add, std::ratio<2,5> >::num == 11

std::ratio_add, std::ratio<2,5> >::den == 15

std::ratio_add, std::ratio<7,6> >::num == 3

std::ratio_add, std::ratio<7,6> >::den == 2

D.6.3. Псевдоним шаблона
std::ratio_subtract

Псевдоним шаблона

std::ratio_subtract
предоставляет механизм вычитания двух значений
std::ratio
на этапе компиляции с применением правил арифметических операций с рациональными числами.

Определение

template 

using ratio_subtract = std::ratio<см. ниже>;

Предусловия

R1
и
R2
должны быть конкретизациями шаблона
std::ratio
.

Результат

ratio_subtract
определяется как псевдоним конкретизации
std::ratio
, представляющий разность дробей, представленных параметрами
R1
и
R2
, если эту разность можно вычислить без переполнения. Если при вычислении возникает переполнение, то программа считается некорректной. В отсутствии переполнения
std::ratio_subtract
будет иметь такие же значения
num
и
den
, как в конкретизации
std::ratio
.

Примеры

std::ratio_subtract, std::ratio<1,5> >::num == 2

std::ratio_subtract, std::ratio<1,5> >::den == 15

std::ratio_subtract, std::ratio<7,6> >::num == -5

std::ratio_subtract, std::ratio<7,6> >::den == 6

D.6.4. Псевдоним шаблона
std::ratio_multiply

Псевдоним шаблона

std::ratio_multiply
предоставляет механизм умножения двух значений
std::ratio
на этапе компиляции с применением правил арифметических операций с рациональными числами.

Определение

template 

using ratio_multiply = std::ratio<см. ниже>;

Предусловия

R1
и
R2
должны быть конкретизациями шаблона
std::ratio
.

Результат

ratio_multiply
определяется как псевдоним конкретизации
std::ratio
, представляющий произведение дробей, представленных параметрами
R1
и
R2
, если это произведение можно вычислить без переполнения. Если при вычислении возникает переполнение, то программа считается некорректной. В отсутствии переполнения
std::ratio_multiply
будет иметь такие же значения
num
и
den
, как в конкретизации
std::ratio
.

Примеры

std::ratio_multiply, std::ratio<2,5> >::num == 2

std::ratio_multiply, std::ratio<2,5> >::den == 15

std::ratio_multiply, std::ratio<15,7> >::num == 5

std::ratio_multiply, std::ratio<15,7> >::den == 7

D.6.5. Псевдоним шаблона
std::ratio_divide

Псевдоним шаблона

std::ratio_divide
предоставляет механизм деления двух значений
std::ratio
на этапе компиляции с применением правил арифметических операций с рациональными числами.

Определение

template 

using ratio_divide = std::ratio<см. ниже>;

Предусловия

R1
и
R2
должны быть конкретизациями шаблона
std::ratio
.

Результат

ratio_divide
определяется как псевдоним конкретизации
std::ratio
, представляющий частное дробей, представленных параметрами
R1
и
R2
, если это частное можно вычислить без переполнения. Если при вычислении возникает переполнение, то программа считается некорректной. В отсутствии переполнения
std::ratio_divide
будет иметь такие же значения
num
и
den
, как в конкретизации
std::ratio
.

Примеры

std::ratio_divide, std::ratio<2,5> >::num == 5

std::ratio_divide, std::ratio<2,5> >::den == 6

std::ratio_divide, std::ratio<15,7> >::num == 7

std::ratio_divide, std::ratio<15,7> >::den == 45

D.6.6. Шаблон класса
std::ratio_equal

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

std::ratio_equal
предоставляет механизм сравнения двух значений
std::ratio
на этапе компиляции с применением правил арифметических операций с рациональными числами.

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

template 

class ratio_equal:

 public std::integral_constant<

  bool, (R1::num == R2::num) && (R1::den == R2::den)> {};

Предусловия

R1
и
R2
должны быть конкретизациями шаблона
std::ratio
.

Примеры

std::ratio_equal, std::ratio<2,6> >::value

 == true

std::ratio_equal, std::ratio<1,6> >::value

 == false

std::ratio_equal, std::ratio<2,3> >::value

 == false

std::ratio_equal, std::ratio<1,3> >::value

 == true

D.6.7. Шаблон класса
std::ratio_not_equal

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

std::ratio_not_equal
предоставляет механизм сравнения двух значений
std::ratio
на этапе компиляции с применением правил арифметических операций с рациональными числами.

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

template 

class ratio_not_equal:

 public std::integral_constant<

  bool, !ratio_equal::value> {};

Предусловия

R1
и
R2
должны быть конкретизациями шаблона
std::ratio
.

Примеры

std::ratio_not_equal<

 std::ratio<1,3>, std::ratio<2,6> >::value == false

std::ratio_not_equal<

 std::ratio<1,3>, std::ratio<1,6> >::value == true

std::ratio_not_equal<

 std::ratio<1,3>, std::ratio<2,3> >::value == true

std::ratio_not_equal<

 std::ratio<1,3>, std::ratio<1,3> >::value == false

D.6.8. Шаблон класса
std::ratio_less

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

std::ratio_less
предоставляет механизм сравнения двух значений
std::ratio
на этапе компиляции с применением правил арифметических операций с рациональными числами.

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

template 

class ratio_less:

 public std::integral_constantсм. ниже> {};

Предусловия

R1
и
R2
должны быть конкретизациями шаблона
std::ratio
.

Результат

std::ratio_less
наследует шаблону
std::integral_constant
, где
value
— это
(R1::num*R2::den) < (R2::num*R1::den)
. Если возможно, реализация должна использовать такой метод вычисления результата, при котором не возникает переполнения. Если при вычислении возникает переполнение, то программа считается некорректной.

Примеры

std::ratio_less, std::ratio<2,6> >::value

 == false

std::ratio_less, std::ratio<1,3> >::value

 == true

std::ratio_less<

 std::ratio<999999999,1000000000>,

 std::ratio<1000000001,1000000000> >::value == true

std::ratio_less<

 std::ratio<1000000001,1000000000>,

 std::ratio<999999999,1000000000> >::value == false

D.6.9. Шаблон класса
std::ratio_greater

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

std::ratio_greater
предоставляет механизм сравнения двух значений
std::ratio
на этапе компиляции с применением правил арифметических операций с рациональными числами.

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

template 

class ratio_greater:

 public std::integral_constant<

  bool, ratio_less::value> {};

Предусловия

R1
и
R2
должны быть конкретизациями шаблона
std::ratio
.

D.6.10. Шаблон класса
std::ratio_less_equal

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

std::ratio_less_equal
предоставляет механизм сравнения двух значений
std::ratio
на этапе компиляции с применением правил арифметических операций с рациональными числами.

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

template 

class ratio_less_equal:

 public std::integral_constant<

  bool, !ratio_less::value> {};

Предусловия

R1
и
R2
должны быть конкретизациями шаблона
std::ratio
.

D.6.11. Шаблон класса
std::ratio_greater_equal

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

std::ratio_greater_equal
предоставляет механизм сравнения двух значений
std::ratio
на этапе компиляции с применением правил арифметических операций с рациональными числами.

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

template 

class ratio_greater_equal:

 public std::integral_constant<

  bool, !ratio_less::value> {};

Предусловия

R1
и
R2
должны быть конкретизациями шаблона
std::ratio
.

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

В заголовке

объявлены средства для идентификации и управления потоками, а также функции для приостановки потоков.

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

namespace std {


class thread;


namespace this_thread {

thread::id get_id() noexcept;


void yield() noexcept;


template

void sleep_for(

 std::chrono::duration sleep_duration);


template

void sleep_until(

 std::chrono::time_point wake_time);

}

}

D.7.1. Класс
std::thread

Класс s

td::thread
применяется для управления потоком выполнения. В нем имеются средства для запуска нового потока и ожидания завершения потока, а также для идентификации потоков. Также в класс включены другие функции для управления потоком выполнения.

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

class thread {

public:

 // Типы

 class id;

 typedef implementation-defined

 native_handle_type; // необязательно


 // Конструкторы и деструкторы

 thread() noexcept;

 ~thread();


 template

 explicit thread(Callable&& func, Args&&... args);


 // Копирование и перемещение

 thread(thread const& other) = delete;

 thread(thread&& other) noexcept;


 thread& operator=(thread const& other) = delete;

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


 void swap(thread& other) noexcept;


 void join();

 void detach();

 bool joinable() const noexcept;


 id get_id() const noexcept;


 native_handle_type native_handle();


 static unsigned hardware_concurrency() noexcept;

};


void swap(thread& lhs, thread& rhs);


              STD::THREAD::ID
            
, КЛАСС

Экземпляр класса

std::thread::id
идентифицирует конкретный поток выполнения.

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

class thread::id {

public:

 id() noexcept;

};


bool operator==(thread::id x, thread::id y) noexcept;

bool operator!=(thread::id x, thread::id y) noexcept;

bool operator<(thread::id x, thread::id y) noexcept;

bool operator<=(thread::id x, thread::id y) noexcept;

bool operator>(thread::id x, thread::id y) noexcept;

bool operator>=(thread::id x, thread::id y) noexcept;


template

basic_ostream&

 operator<<(basic_ostream&& out, thread::id id);

Примечание. Значение

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

Примечание. Значения

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

Экземпляры

std::thread::id
удовлетворяют требованиям концепций
CopyConstructible
и
CopyAssignable
, поэтому их можно копировать и присваивать друг другу


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

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

std::thread::id
, который не представляет никакой поток выполнения.

Объявление

id() noexcept;

Результат

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

std::thread::id
, с которым связано особое значение, интерпретируемое как не поток.

Исключения

Нет.

Примечания. Во всех сконструированных по умолчанию экземпляров

std::thread::id
хранится одно и то же значение.


              STD::THREAD::ID
            
, ОПЕРАТОР СРАВНЕНИЯ НА РАВЕНСТВО

Сравнивает два экземпляра

std::thread::id
, проверяя, представляют ли они один и тот же поток.

Объявление

bool operator==(

 std::thread::id lhs, std::thread::id rhs) noexcept;

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

true
, если
lhs
и
rhs
представляют один и тот же поток выполнения или оба имеют значение не поток,
false
, если
lhs
и
rhs
представляют разные потоки или один представляет поток, а другой имеет значение не поток.

Исключения

Нет.


              STD::THREAD::ID
            
, ОПЕРАТОР СРАВНЕНИЯ НА НЕРАВЕНСТВО

Сравнивает два экземпляра

std::thread::id
, проверяя, представляют ли они разные потоки.

Объявление

bool operator!=(

 std::thread::id lhs, std::thread::id rhs) noexcept;

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

!(lhs==rhs)

Исключения

Нет.


              STD::THREAD::ID
            
, ОПЕРАТОР СРАВНЕНИЯ МЕНЬШЕ

Сравнивает два экземпляра

std::thread::id
, проверяя, предшествует ли один из них другому в смысле отношения полного порядка, существующего на множестве значений идентификаторов потоков.

Объявление

bool operator<(

 std::thread::id lhs, std::thread::id rhs) noexcept;

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

true
, если значение
lhs
предшествует значению
rhs
в смысле отношения полного порядка, существующего на множестве значений идентификаторов потоков. Если
lhs != rhs
, то истинно ровно одно из утверждений
lhs < rhs
и
rhs < lhs
, тогда как второе ложно. Если
lhs == rhs
, то оба утверждения
lhs < rhs
и
rhs < lhs
ложны.

Исключения

Нет.

Примечание. Особое значение не поток, которое хранится в сконструированном по умолчанию экземпляре

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


              STD::THREAD::ID
            
, ОПЕРАТОР СРАВНЕНИЯ МЕНЬШЕ ИЛИ РАВНО

Сравнивает два экземпляра

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

Объявление

bool operator<=(

 std::thread::id lhs, std::thread::id rhs) noexcept;

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

!(rhs < lhs)

Исключения

Нет.


              STD::THREAD::ID
            
, ОПЕРАТОР СРАВНЕНИЯ БОЛЬШЕ

Сравнивает два экземпляра

std::thread::id
, проверяя, следует ли один из них за другим в смысле отношения полного порядка, существующего на множестве значений идентификаторов потоков.

Объявление

bool operator>(

 std::thread::id lhs, std::thread::id rhs) noexcept;

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

rhs < lhs

Исключения

Нет.


              STD::THREAD::ID
            
, ОПЕРАТОР СРАВНЕНИЯ БОЛЬШЕ ИЛИ РАВНО

Сравнивает два экземпляра

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

Объявление

bool operator>=(

 std::thread::id lhs, std::thread::id rhs) noexcept;

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

!(lhs < rhs)

Исключения

Нет.


              STD::THREAD::ID
            
, ОПЕРАТОР ВСТАВКИ В ПОТОК

Выводит строковое представление значения

std::thread::id
в указанный поток.

Объявление

template

basic_ostream&

operator<<(basic_ostream&& out, thread::id id);

Результат

Выводит строковое представление значения

std::thread::id
в указанный поток. Возвращаемое значение

out

Исключения

Нет.

Примечание. Формат строкового представления не специфицирован. Равные экземпляры имеют одинаковое представление, неравные — различное.


              STD::THREAD::NATIVE_HANDLE_TYPE
            
, ПСЕВДОНИМ ТИПА

native_handle_type
— это псевдоним типа, который можно использовать в сочетании с платформенно-зависимыми API.

Объявление

typedef implementation-defined native_handle_type;

Примечание. Этот псевдоним типа необязателен. Если он определен, то реализация должна предоставить тип, пригодный для использования в сочетании с платформенно-зависимыми API.


              STD::THREAD::NATIVE_HANDLE
            
, ФУНКЦИЯ-ЧЛЕН

Возвращает значение типа

native_handle_type
, представляющее поток выполнения, ассоциированный с
*this
.

Объявление

native_handle_type native_handle();

Примечание. Эта функция необязательна. Если она имеется, то возвращаемое значение должно быть пригодно для использования в сочетании с платформенно-зависимыми API.


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

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

std::thread
, с которым не ассоциирован никакой поток выполнения.

Объявление

thread() noexcept;

Результат

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

std::thread
, с которым не ассоциирован никакой поток выполнения.

Постусловия

Для вновь сконструированного объекта x типа

std::thread x.get_id()==id()
.

Исключения

Нет.


              STD::THREAD
            
, КОНСТРУКТОР

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

std::thread
, ассоциированный с новым потоком выполнения.

Объявление

template

explicit thread(Callable&& func, Args&&... args);

Предусловия

func
и каждый элемент списка
args
должен удовлетворять требованиям концепции
MoveConstructible
.

Результат

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

std::thread
и ассоциирует с ним вновь созданный потоком выполнения. Копирует или перемещает аргумент
func
и все элементы списка
args
во внутреннюю память, где они хранятся на протяжении всего времени жизни потока выполнения. Вызывает
INVOKE(copy-of-func, copy-of-args)
в новом потоке выполнения.

Постусловия

Для вновь сконструированного объекта

x
типа
std::thread x.get_id() != id()
.

Исключения

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

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

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

Вызов этого конструктора происходит-раньше выполнения переданной функции во вновь созданном потоке выполнения.


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

Передает владение потоком выполнения от существующего объекта

std::thread
вновь созданному.

Объявление

thread(thread&& other) noexcept;

Результат

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

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

Постусловия

Для вновь сконструированного объекта

x
типа
std::thread x.get_id()
равно значению
other.get_id()
до вызова конструктора,
other.get_id() == id()
.

Исключения

Нет.

Примечание. Объекты

std::thread
не удовлетворяют требованиям концепции
CopyConstructible
, поэтому копирующего конструктора не существует, существует только этот перемещающий конструктор.


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

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

std::thread
.

Объявление

~thread();

Результат

Уничтожает

*this
. Если с
*this
ассоциирован поток выполнения (
this->joinable()
возвращает
true
), то вызывает
std::terminate()
, то есть аварийно завершает программу.

Исключения

Нет.


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

Передает владение потоком выполнения от одного объекта

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

Объявление

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

Результат

Если до вызова этого оператора

this->joinable()
возвращала
true
, то вызывает
std::terminate()
для аварийного завершения программы. Если с
other
до вызова оператора был ассоциирован поток выполнения, то после вызова он оказывается ассоциирован с
*this
. В противном случае с
*this
не ассоциирован никакой поток выполнения.

Постусловия

this->get_id()
равно значению
other.get_id()
до вызова конструктора.
other.get_id() == id()
.

Исключения

Нет.

Примечание. Объекты

std::thread
не удовлетворяют требованиям концепции
CopyAssignable
, поэтому копирующего оператора присваивания не существует, существует только этот перемещающий оператор присваивания.


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

Обменивает владение ассоциированными потоками выполнения между двумя объектами

std::thread
.

Объявление

void swap(thread& other) noexcept;

Результат

Если с

other
до вызова функции был ассоциирован поток выполнения, то после вызова он оказывается ассоциирован с
*this
. В противном случае с
*this
не ассоциирован никакой поток выполнения. Если с
*this
до вызова функции был ассоциирован поток выполнения, то после вызова он оказывается ассоциирован с
other
. В противном случае с
other
не ассоциирован никакой поток выполнения.

Постусловия

this->get_id()
равно значению
other.get_id()
до вызова функции.
other.get_id()
равно значению
this->get_id()
до вызова функции.

Исключения

Нет.


              STD::THREAD::SWAP
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Обменивает владение ассоциированными потоками выполнения между двумя объектами

std::thread
.

Объявление

void swap(thread& lhs, thread& rhs) noexcept;

Результат

lhs.swap(rhs)

Исключения

Нет.


              STD::THREAD::JOINABLE
            
, ФУНКЦИЯ-ЧЛЕН

Опрашивает, ассоциирован ли с

*this
поток выполнения.

Объявление

bool joinable() const noexcept;

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

true
, если с
*this
ассоциирован поток выполнения, иначе
false
.

Исключения

Нет.


              STD::THREAD::JOIN
            
, ФУНКЦИЯ-ЧЛЕН

Ожидает завершения потока выполнения, ассоциированного с

*this
.

Объявление

void jоin();

Предусловия

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

Результат

Блокирует текущий поток, пока не завершится поток, ассоциированный с

*this
.

Постусловия

this->get_id() == id()
. Поток выполнения, который был ассоциирован с
*this
до вызова этой функции, завершился.

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

Завершение потока выполнения, который был ассоциирован с

*this
до вызова этой функции, происходит-раньше возврата из
jоin()
.

Исключения

std::system_error
, если требуемого эффекта добиться не удалось или если
this->joinable()
возвращает
false
.


              STD::THREAD::DETACH
            
, ФУНКЦИЯ-ЧЛЕН

Отсоединяет поток выполнения, ассоциированный с

*this
.

Объявление

void detach();

Предусловия

this->joinable()
возвращает
true
.

Результат

Отсоединяет поток выполнения, ассоциированный с

*this
.

Постусловия

this->get_id() == id()
,
this->joinable() == false
. Поток выполнения, который был ассоциирован с
*this
до вызова этой функции, отсоединен и более не ассоциирован ни с каким объектом
std::thread
.

Исключения

std::system_error
, если требуемого эффекта добиться не удалось или если
this->joinable()
возвращает
false
в момент вызова.


              STD::THREAD::GET_ID
            
, ФУНКЦИЯ-ЧЛЕН

Возвращает значение типа s

td::thread::id
, идентифицирующее поток выполнения, ассоциированный с
*this
.

Объявление

thread::id get_id() const noexcept;

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

Если с

*this
ассоциирован поток выполнения, то возвращает экземпляр
std::thread::id
, который идентифицирует этот поток. В противном случае возвращает сконструированный по умолчанию экземпляр
std::thread::id
.

Исключения

Нет.


              STD::THREAD::HARDWARE_CONCURRENCY
            
, СТАТИЧЕСКАЯ ФУНКЦИЯ-ЧЛЕН

Возвращает информацию о том, сколько потоков могут одновременно работать на имеющемся оборудовании.

Объявление

unsigned hardware_concurrency() noexcept;

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

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

Исключения

Нет.

D.7.2. Пространство имен
this_thread

Функции из пространства имен

std::this_thread
применяются к вызывающему потоку.


              STD::THIS_THREAD::GET_ID
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Возвращает значение типа

std::thread::id
, идентифицирующее текущий поток выполнения.

Объявление

thread::id get_id() noexcept;

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

Экземпляр

std::thread::id
, идентифицирующий текущий поток выполнения.

Исключения

Нет.


              STD::THIS_THREAD::YIELD
            
, ФУНКЦИЯ, HE ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

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

Объявление

void yield() noexcept;

Результат

Предоставляет библиотеке возможность запланировать другой поток вместо текущего.

Исключения

Нет.


              STD::THIS_THREAD::SLEEP_FOR
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Приостанавливает выполнение текущего потока на указанное время.

Объявление

template

void sleep_for(

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

Результат

Приостанавливает выполнение текущего потока на указанное время

relative_time
.

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

Исключения

Нет.


              STD::THIS_THREAD::SLEEP_UNTIL
            
, ФУНКЦИЯ, НЕ ЯВЛЯЮЩАЯСЯ ЧЛЕНОМ КЛАССА

Приостанавливает выполнение текущего потока до указанного момента времени.

Объявление

template

void sleep_until(

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

Результат

Приостанавливает выполнение текущего потока до наступления момента

absolute_time
по указанным часам
Clock
.

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

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

Исключения

Нет.

Загрузка...