33 Thread support library [thread]

33.4 Mutual exclusion [thread.mutex]

33.4.6 Call once [thread.once]

33.4.6.1 Struct once_­flag [thread.once.onceflag]

namespace std {
  struct once_flag {
    constexpr once_flag() noexcept;

    once_flag(const once_flag&) = delete;
    once_flag& operator=(const once_flag&) = delete;
  };
}

Класс once_­flag представляет собой непрозрачную структуру данных, которая call_­once используется для инициализации данных, не вызывая гонки данных или взаимоблокировки.

constexpr once_flag() noexcept;

Effects: Создает объект типа once_­flag.

Synchronization: Строительство once_­flag объекта не синхронизировано.

Postconditions: Внутреннее состояние объекта устанавливается таким образом, чтобы указать при вызове call_­once объекта в качестве начального аргумента, что функция не была вызвана.

33.4.6.2 Function call_­once [thread.once.callonce]

template<class Callable, class... Args> void call_once(once_flag& flag, Callable&& func, Args&&... args);

Requires:

INVOKE(std::forward<Callable>(func), std::forward<Args>(args)...)

(см. [func.require]) должно быть допустимым выражением.

Effects: Выполнение того, call_­once что не вызывает его, func есть passive казнь. Выполнение call_­once этого вызова func - это active исполнение. Активное исполнение вызовет INVOKE(​std​::​forward<Callable>(func), std​::​forward<Args>(args)...). Если такой вызов func вызывает исключение, выполняется exceptional, в противном случае - это так returning. Исключительное выполнение должно передать исключение вызывающему call_­once. Среди всех выполнений call_­once для любого данного once_­flag: не более одного должно быть повторным выполнением; если есть возвращающееся исполнение, это будет последнее активное выполнение; и есть пассивные казни, только если есть возвращающееся исполнение. [ Note: Пассивное выполнение позволяет другим потокам надежно наблюдать за результатами, полученными ранее выполненным возвратом. ] end note

Synchronization: Для любого данного once_­flag: все активные исполнения происходят в общем порядке; завершение активного выполнения synchronizes with начало следующего в этом общем порядке; и возвращающееся выполнение синхронизируется с возвратом из всех пассивных исполнений.

Throws: system_­error когда требуется исключение ([thread.req.exception]) или любое исключение, созданное func.

[Example:

// global flag, regular function
void init();
std::once_flag flag;

void f() {
  std::call_once(flag, init);
}

// function static flag, function object
struct initializer {
  void operator()();
};

void g() {
  static std::once_flag flag2;
  std::call_once(flag2, initializer());
}

// object flag, member function
class information {
  std::once_flag verified;
  void verifier();
public:
  void verify() { std::call_once(verified, &information::verifier, *this); }
};

end example]