[thread.once] # 32 Concurrency support library [[thread]](./#thread) ## 32.6 Mutual exclusion [[thread.mutex]](thread.mutex#thread.once) ### 32.6.7 Call once [thread.once] #### [32.6.7.1](#onceflag) Struct once_flag [[thread.once.onceflag]](thread.once.onceflag) [🔗](#lib:once_flag) namespace std {struct once_flag {constexpr once_flag() noexcept; once_flag(const once_flag&) = delete; once_flag& operator=(const once_flag&) = delete; };} [1](#onceflag-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9379) The class once_flag is an opaque data structure that call_once uses to initialize data without causing a data race or deadlock[.](#onceflag-1.sentence-1) [🔗](#lib:once_flag_) `constexpr once_flag() noexcept; ` [2](#onceflag-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9389) *Synchronization*: The construction of a once_flag object is not synchronized[.](#onceflag-2.sentence-1) [3](#onceflag-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9393) *Postconditions*: The object's internal state is set to indicate to an invocation ofcall_once with the object as its initial argument that no function has been called[.](#onceflag-3.sentence-1) #### [32.6.7.2](#callonce) Function call_once [[thread.once.callonce]](thread.once.callonce) [🔗](#lib:call_once) `template void call_once(once_flag& flag, Callable&& func, Args&&... args); ` [1](#callonce-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9409) *Mandates*: is_invocable_v is true[.](#callonce-1.sentence-1) [2](#callonce-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9413) *Effects*: An execution of call_once that does not call its func is a[*passive*](#def:passive) execution[.](#callonce-2.sentence-1) An execution of call_once that calls its func is an [*active*](#def:active) execution[.](#callonce-2.sentence-2) An active execution evaluates*INVOKE*(​std​::​forward(func), std​::​forward(args)...) ([[func.require]](func.require "22.10.4 Requirements"))[.](#callonce-2.sentence-3) If such a call to func throws an exception the execution is [*exceptional*](#def:exceptional), otherwise it is [*returning*](#def:returning)[.](#callonce-2.sentence-4) An exceptional execution propagates the exception to the caller ofcall_once[.](#callonce-2.sentence-5) Among all executions of call_once for any givenonce_flag: at most one is a returning execution; if there is a returning execution, it is the last active execution; and there are passive executions only if there is a returning execution[.](#callonce-2.sentence-6) [*Note [1](#callonce-note-1)*: Passive executions allow other threads to reliably observe the results produced by the earlier returning execution[.](#callonce-2.sentence-7) — *end note*] [3](#callonce-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9433) *Synchronization*: For any given once_flag: all active executions occur in a total order; completion of an active execution [synchronizes with](intro.multithread#def:synchronize_with "6.10.2 Multi-threaded executions and data races [intro.multithread]") the start of the next one in this total order; and the returning execution synchronizes with the return from all passive executions[.](#callonce-3.sentence-1) [4](#callonce-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9440) *Throws*: system_error when an exception is required ([[thread.req.exception]](thread.req.exception "32.2.2 Exceptions")), or any exception thrown by func[.](#callonce-4.sentence-1) [5](#callonce-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L9445) [*Example [1](#callonce-example-1)*: // global flag, regular functionvoid init(); std::once_flag flag; void f() { std::call_once(flag, init);}// function static flag, function objectstruct initializer {void operator()();}; void g() {static std::once_flag flag2; std::call_once(flag2, initializer());}// object flag, member functionclass information { std::once_flag verified; void verifier();public:void verify() { std::call_once(verified, &information::verifier, *this); }}; — *end example*]