std::call_once
| <mutex> 에 정의되어 있음.
|
||
template< class Callable, class... Args > void call_once( std::once_flag& flag, Callable&& f, Args&&... args ); |
(since C++11) | |
여러 스레드에서 호출하더라도 Callable 객체 f를 딱 한번만 실행한다.
같은 std::once_flag 객체를 받는 call_once 호출 그룹은 다음 요구사항을 만족한다.:
- 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 above-mentioned execution of the selected function is completed successfully, that is, doesn't exit via an exception.
- 해당 함수에서 예외가 발생하면 호출자로 전파된다. 그런 다음 다른 함수가 선택되어 실행된다.
인자
| flag | - | 함수가 정확히 한번만 실행되게 하는 객체 |
| f | - | 호출되는 Callable 객체
|
| args... | - | 함수로 전달되는 인자들 |
반환값
(없음)
예외
- std::system_error if any condition prevents calls to
call_oncefrom executing as specified f가 발생시키는 모든 예외
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.
예제
#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
참고
(C++11) |
helper object to ensure that call_once invokes the function only once (class) |
C documentation for call_once
| |