Files
2025-10-25 03:02:53 +03:00

110 lines
4.5 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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<class Callable, class... Args>
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<Callable, Args...> 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<Callable>(func),
std::forward<Args>(args)...) ([[func.require]](func.require "22.10.4Requirements"))[.](#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.2Multi-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.2Exceptions")), 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*]