std::call_once
| Defined in header <mutex>
|
||
| template< class Callable, class... Args > void call_once( std::once_flag& flag, Callable&& f, Args&&... args ); |
(since C++11) | |
Executes the Callable object f exactly once, even if called from several threads.
Each group of call_once invocations that receives the same std::once_flag object will meet the following requirements:
- Exactly one execution of exactly one of the functions (passed as
fto the invocations in the group) is performed. It is undefined which function will be selected for execution. The selected function runs in the same thread as thecall_onceinvocation it was passed to.
- No invocation in the group returns before the abovementioned execution of the selected function is completed successfully, that is, doesn't exit via an exception.
- If the selected function exits via exception, it is propagated to the caller. Another function is then selected and executed.
Contents |
[edit] Parameters
| flag | - | an object, for which exactly one function gets executed |
| f | - | Callable object to invoke
|
| args... | - | arguments to pass to the function |
[edit] Return value
(none)
[edit] Exceptions
- std::system_error if any condition prevents calls to
call_oncefrom executing as specified - any exception thrown by
f
[edit] Notes
|
The arguments to the |
(until C++17) |
|
The arguments to the |
(since C++17) |
Initialization of function-local statics is guaranteed to occur only once even when called from multiple threads, and may be more efficient than the equivalent code using std::call_once.
[edit] Example
#include <iostream> #include <thread> #include <mutex> std::once_flag flag1, flag2; void simple_do_once() { std::call_once(flag1, [](){ std::cout << "Simple example: called once\n"; }); } void may_throw_function(bool do_throw) { if (do_throw) { std::cout << "throw: call_once will retry\n"; // this may appear more than once throw std::exception(); } std::cout << "Didn't throw, call_once will not attempt again\n"; // guaranteed once } void do_once(bool do_throw) { try { std::call_once(flag2, may_throw_function, do_throw); } catch (...) { } } int main() { std::thread st1(simple_do_once); std::thread st2(simple_do_once); std::thread st3(simple_do_once); std::thread st4(simple_do_once); st1.join(); st2.join(); st3.join(); st4.join(); std::thread t1(do_once, true); std::thread t2(do_once, true); std::thread t3(do_once, false); std::thread t4(do_once, true); t1.join(); t2.join(); t3.join(); t4.join(); }
Possible output:
Simple example: called once throw: call_once will retry throw: call_once will retry Didn't throw, call_once will not attempt again
[edit] See also
| (C++11) |
helper object to ensure that call_once invokes the function only once (class) |
| C documentation for call_once
| |