개발/C, C++
C++ - call_once로 함수를 한 번만 호출하기
피로물든딸기
2024. 1. 24. 23:42
반응형
test 함수는 처음 호출 되는 경우에만 init을 수행한다.
#include <iostream>
using namespace std;
bool first;
void test()
{
if (first == false)
{
first = true;
cout << "init" << endl;
}
cout << "function end." << endl;
}
int main()
{
test();
test();
test();
return 0;
}
한 번만 실행되는 블럭인데 매번 명시적으로 조건문을 체크해야 한다.
if (first == false)
{
first = true;
cout << "init" << endl;
}
std::call_once
C++11에서 제공되는 <mutex>의 std::call_once를 이용하면 특정 함수를 한 번만 호출할 수 있다.
call_once를 사용하면 명시적인 조건문을 사용하지 않아도 된다.
아래 코드를 실행해 보자.
std::once_flag 객체를 사용하여 초기화 함수가 한 번만 호출되도록 보장한다.
#include <iostream>
#include <mutex>
using namespace std;
once_flag flag;
void test()
{
call_once(flag, []() {
cout << "init" << endl;
});
cout << "function end." << endl;
}
int main()
{
test();
test();
test();
return 0;
}
그리고 call_once 내부의 블럭을 함수로 변경할 수도 있다.
void init()
{
cout << "init" << endl;
}
void test()
{
call_once(flag, init);
cout << "function end." << endl;
}
mutex는 동시성 관련 헤더이며, 여러 스레드에서 동시에 해당 함수를 호출할 때,
특정 함수를 한 번만 호출하도록 보장하기 위해 call_once를 사용한다.
#include <iostream>
#include <mutex>
using namespace std;
once_flag flag;
void init()
{
cout << "init" << endl;
}
void test()
{
call_once(flag, init);
cout << "function end." << endl;
}
int main()
{
thread t1(test);
thread t2(test);
thread t3(test);
t1.join();
t2.join();
t3.join();
return 0;
}
매개변수 전달
call_once를 사용하는 함수에 인자를 전달해야 하는 경우는 람다 함수를 이용하면 된다.
[capture](parameters) -> return_type {
// 함수 구현
}
사용 예시는 다음과 같다.
#include <iostream>
#include <mutex>
using namespace std;
once_flag flag;
void init(int val1, int val2)
{
cout << "init : " << val1 << ", " << val2 << endl;
}
void test(int val1, int val2)
{
call_once(flag, [val1, val2]() {
init(val1, val2);
});
cout << "function end." << endl;
}
int main()
{
thread t1(test, 1, 2);
thread t2(test, 3, 4);
thread t3(test, 5, 6);
t1.join();
t2.join();
t3.join();
return 0;
}
반응형